Changes in / [04b73b6:f0c3120]


Ignore:
Files:
1 added
5 deleted
27 edited

Legend:

Unmodified
Added
Removed
  • benchmark/io/http/filecache.cfa

    r04b73b6 rf0c3120  
    5656}
    5757
    58 static inline [unsigned size, char unit] human_size( size_t size ) {
    59         int idx = 0;
    60         static char units [] = { ' ', 'K', 'M', 'G', 'T' };
    61         while( size >= 1024 ) {
    62                 idx++;
    63                 size /= 1024;
    64                 if(idx >= 5) {
    65                         abort("File too large to print\n");
    66                 }
    67         }
    68 
    69         return [size, units[idx]];
    70 }
    7158
    7259struct {
     
    8269
    8370[int fd, size_t size] get_file( * const char file, size_t len ) {
    84         uint32_t idx = murmur3_32( (const uint8_t *)file, len, options.file_cache.hash_seed ) % file_cache.size;
     71        uint32_t idx = murmur3_32( (const uint8_t *)file, len, options.hash_seed ) % file_cache.size;
    8572
    8673        for(int i = 0;; i++) {
     
    9986
    10087int put_file( cache_line & entry ) {
    101         uint32_t idx = murmur3_32( (const uint8_t *)entry.file, strlen(entry.file), options.file_cache.hash_seed ) % file_cache.size;
     88        uint32_t idx = murmur3_32( (const uint8_t *)entry.file, strlen(entry.file), options.hash_seed ) % file_cache.size;
    10289
    10390        int i = 0;
     
    114101void fill_cache( const char * path ) {
    115102        int ret;
    116         ret = chdir(path);
    117         if(ret < 0) {
    118                 abort( "chdir error: (%d) %s\n", (int)errno, strerror(errno) );
    119         }
    120 
    121103        size_t fcount = 0;
    122104        size_t fsize = 16;
     
    136118                raw[idx].file = strdup(fpath+2);
    137119                raw[idx].size = sb->st_size;
    138                 if( !options.file_cache.list ) {
    139                         raw[idx].fd = open( fpath, options.file_cache.open_flags );
    140                         if(raw[idx].fd < 0) {
    141                                 abort( "open file error: (%d) %s\n", (int)errno, strerror(errno) );
    142                         }
     120                raw[idx].fd = open( fpath, options.open_flags );
     121                if(raw[idx].fd < 0) {
     122                        abort( "open file error: (%d) %s\n", (int)errno, strerror(errno) );
    143123                }
    144124                return 0;
    145125        }
    146126
    147         ret = ftw(".", walk, 10);
     127        ret = ftw(path, walk, 10);
    148128        if(ret < 0) {
    149129                abort( "ftw error: (%d) %s\n", (int)errno, strerror(errno) );
     
    155135
    156136        // Step 2 create the cache
    157         file_cache.size = options.file_cache.size > 0 ? options.file_cache.size : fsize;
     137        file_cache.size = options.file_cache_size > 0 ? options.file_cache_size : fsize;
    158138        if( file_cache.size < fcount ) {
    159139                abort("File Cache too small\n");
    160140        }
    161141
    162         file_cache.entries = anew(file_cache.size);
     142        file_cache.entries = anew(fsize);
    163143
    164144        // Step 3 fill the cache
    165145        int conflicts = 0;
    166146        for(i; fcount) {
     147                printf("Added file %s\n", raw[i].file);
    167148                conflicts += put_file( raw[i] );
    168149        }
    169150        printf("Filled cache from path \"%s\" with %zu files\n", path, fcount);
    170151        if( conflicts > 0 ) {
    171                 printf("Found %d conflicts (seed: %u)\n", conflicts, options.file_cache.hash_seed);
     152                printf("Found %d conflicts (seed: %u)\n", conflicts, options.hash_seed);
    172153                #if defined(REJECT_CONFLICTS)
    173154                        abort("Conflicts found in the cache");
     
    175156        }
    176157
    177         if(options.file_cache.list) {
    178                 printf("Listing files and exiting\n");
    179                 for(i; fcount) {
    180                         int s; char u;
    181                         [s, u] = human_size(raw[i].size);
    182                         printf("%4d%c - %s\n", s, u, raw[i].file);
    183                         free(raw[i].file);
    184                 }
    185                 free(raw);
    186                 adelete(file_cache.size, file_cache.entries);
    187                 exit(0);
    188         }
    189 
    190158        // Step 4 clean up
    191159        free( raw );
    192160}
    193 
    194 [int *, int] filefds(int extra) {
    195         if(!file_cache.entries) {
    196                 abort("File cache not filled!\n");
    197         }
    198 
    199         return [aalloc(extra), 0];
    200 }
    201 
    202161
    203162void close_cache() {
  • benchmark/io/http/filecache.hfa

    r04b73b6 rf0c3120  
    1111[int fd, size_t size] get_file( * const char file, size_t len );
    1212void fill_cache( const char * path );
    13 [int *, int] filefds( int extra );
    1413void close_cache();
  • benchmark/io/http/main.cfa

    r04b73b6 rf0c3120  
    1717#include "filecache.hfa"
    1818#include "options.hfa"
     19#include "parseargs.hfa"
    1920#include "worker.hfa"
    2021
     
    2223// Globals
    2324//=============================================================================================
     25Options options @= {
     26        0,
     27        42u,
     28        0,
     29        false,
     30        false,
     31        0
     32};
     33
    2434channel & wait_connect;
    2535
     
    2939
    3040void ?{}( ServerProc & this ) {
    31         /* paranoid */ assert( options.clopts.instance != 0p );
    32         (this.self){ "Benchmark Processor", *options.clopts.instance };
     41        /* paranoid */ assert( options.the_cluster != 0p );
     42        (this.self){ "Benchmark Processor", *options.the_cluster };
    3343
    3444        #if !defined(__CFA_NO_STATISTICS__)
    35                 if( options.clopts.procstats ) {
    36                         print_stats_at_exit( this.self, options.clopts.instance->print_stats );
     45                if( options.procstats ) {
     46                        print_stats_at_exit( this.self, options.the_cluster->print_stats );
    3747                }
    38                 if( options.clopts.viewhalts ) {
     48                if( options.viewhalts ) {
    3949                        print_halts( this.self );
    4050                }
     
    4656//============================================================================================='
    4757int main( int argc, char * argv[] ) {
     58        int port      = 8080;
     59        int backlog   = 10;
     60        int nprocs    = 1;
     61        int nworkers  = 1;
     62        int cl_flags  = 0;
     63        int chan_size = 10;
     64        const char * path = ".";
    4865        //===================
    4966        // Parse args
    50         const char * path = parse_options(argc, argv);
     67        static cfa_option opt[] = {
     68                {'p', "port", "Port the server will listen on", port},
     69                {'c', "cpus", "Number of processors to use", nprocs},
     70                {'t', "threads", "Number of worker threads to use", nworkers},
     71                {'b', "accept-backlog", "Maximum number of pending accepts", backlog},
     72                {'B', "channel-size", "Maximum number of accepted connection pending", chan_size}
     73        };
     74        int opt_cnt = sizeof(opt) / sizeof(cfa_option);
     75
     76        char **left;
     77      parse_args( argc, argv, opt, opt_cnt, "[OPTIONS] [PATH]  -- cforall http server", left );
     78
    5179
    5280        //===================
     
    5785        //===================
    5886        // Open Socket
    59         printf("Listening on port %d\n", options.socket.port);
     87        printf("Listening on port %d\n", port);
    6088        int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    6189        if(server_fd < 0) {
     
    6997        address.sin_family = AF_INET;
    7098        address.sin_addr.s_addr = htonl(INADDR_ANY);
    71         address.sin_port = htons( options.socket.port );
     99        address.sin_port = htons( port );
    72100
    73101        ret = bind( server_fd, (struct sockaddr *)&address, sizeof(address) );
     
    76104        }
    77105
    78         ret = listen( server_fd, options.socket.backlog );
     106        ret = listen( server_fd, backlog );
    79107        if(ret < 0) {
    80108                abort( "listen error: (%d) %s\n", (int)errno, strerror(errno) );
     
    84112        // Run Server Cluster
    85113        {
    86                 cluster cl = { "Server Cluster", options.clopts.flags };
     114                cluster cl = { "Server Cluster", cl_flags };
    87115                #if !defined(__CFA_NO_STATISTICS__)
    88116                        print_stats_at_exit( cl, CFA_STATS_READY_Q | CFA_STATS_IO );
    89117                #endif
    90                 options.clopts.instance = &cl;
     118                options.the_cluster = &cl;
    91119
    92                 channel chan = { options.clopts.chan_size };
     120                channel chan = { chan_size };
    93121                &wait_connect = &chan;
    94122
    95                 int pipe_cnt = options.clopts.nworkers * 2;
    96                 int pipe_off;
    97                 int * fds;
    98                 [fds, pipe_off] = filefds( pipe_cnt );
    99                 for(i; 0 ~ pipe_cnt ~ 2) {
    100                         int ret = pipe(&fds[pipe_off + i]);
    101                         if( ret < 0 ) { abort( "pipe error: (%d) %s\n", (int)errno, strerror(errno) ); }
    102                 }
    103 
    104123                {
    105                         ServerProc procs[options.clopts.nprocs];
     124                        ServerProc procs[nprocs];
    106125                        {
    107                                 Worker workers[options.clopts.nworkers];
    108                                 for(i; options.clopts.nworkers) {
    109                                         if( options.file_cache.fixed_fds ) {
    110                                                 workers[i].pipe[0] = pipe_off + (i * 2) + 0;
    111                                                 workers[i].pipe[1] = pipe_off + (i * 2) + 1;
    112                                         }
    113                                         else {
    114                                                 workers[i].pipe[0] = fds[pipe_off + (i * 2) + 0];
    115                                                 workers[i].pipe[1] = fds[pipe_off + (i * 2) + 1];
    116                                         }
    117                                         unpark( workers[i] __cfaabi_dbg_ctx2 );
    118                                 }
    119                                 printf("%d workers started on %d processors\n", options.clopts.nworkers, options.clopts.nprocs);
     126                                Worker workers[nworkers];
     127                                printf("%d workers started on %d processors\n", nworkers, nprocs);
    120128                                {
    121129                                        Acceptor acceptor = { server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen, 0 };
    122 
    123                                         char buffer[128];
    124                                         while(!feof(stdin)) {
    125                                                 fgets(buffer, 128, stdin);
    126                                         }
    127 
    128                                         printf("Shutting Down\n");
    129130                                }
    130                                 printf("Acceptor Closed\n");
     131                                printf("Shutting Down\n");
    131132
    132133                                // Clean-up the workers
    133                                 for(options.clopts.nworkers) {
     134                                for(nworkers) {
    134135                                        put( wait_connect, -1 );
    135136                                }
    136137                        }
    137                         printf("Workers Closed\n");
    138138                }
    139 
    140                 for(i; pipe_cnt) {
    141                         ret = close( fds[pipe_off + i] );
    142                         if(ret < 0) {
    143                                 abort( "close pipe error: (%d) %s\n", (int)errno, strerror(errno) );
    144                         }
    145                 }
    146                 free(fds);
    147139        }
    148140
  • benchmark/io/http/options.hfa

    r04b73b6 rf0c3120  
    66
    77struct Options {
    8         struct {
    9                 int open_flags;
    10                 uint32_t hash_seed;
    11                 size_t size;
    12                 bool list;
    13                 bool fixed_fds;
    14         } file_cache;
    15 
    16         struct {
    17                 int port;
    18                 int backlog;
    19                 int buflen;
    20         } socket;
    21 
    22         struct {
    23                 int nprocs;
    24                 int nworkers;
    25                 int flags;
    26                 int chan_size;
    27                 bool procstats;
    28                 bool viewhalts;
    29                 cluster * instance;
    30         } clopts;
     8        int open_flags;
     9        uint32_t hash_seed;
     10      size_t file_cache_size;
     11        bool procstats;
     12        bool viewhalts;
     13        cluster * the_cluster;
    3114};
    3215
    3316extern Options options;
    34 
    35 const char * parse_options( int argc, char * argv[] );
  • benchmark/io/http/parseargs.cfa

    r04b73b6 rf0c3120  
    33// #include <stdio.h>
    44// #include <stdlib.h>
    5 #include <errno.h>
    65#include <string.h>
    7 #include <unistd.h>
    86extern "C" {
    97        #include <getopt.h>
    10         #include <sys/ioctl.h>
    118
    129        struct FILE;
     
    1411        extern FILE * stdout;
    1512
    16         extern int fileno(FILE *stream);
    17 
    1813        extern int fprintf ( FILE * stream, const char * format, ... );
    19 
    20         extern          long long int strtoll (const char* str, char** endptr, int base);
    21         extern unsigned long long int strtoull(const char* str, char** endptr, int base);
    22 }
    23 
    24 #include <common.hfa>
    25 #include <limits.hfa>
    26 
    27 void printopt(FILE * out, int width, int max, char sn, const char * ln, const char * help) {
    28         int hwidth = max - (11 + width);
    29         if(hwidth <= 0) hwidth = max;
    30 
    31         fprintf(out, "  -%c, --%-*s   %.*s\n", sn, width, ln, hwidth, help);
    32         for() {
    33                 help += min(strlen(help), hwidth);
    34                 if('\0' == *help) break;
    35                 fprintf(out, "%*s%.*s\n", width + 11, "", hwidth, help);
    36         }
     14        extern long long int strtoll (const char* str, char** endptr, int base);
    3715}
    3816
     
    4725        struct option optarr[opt_count + 2];
    4826        int width = 0;
    49         int max_width = 1_000_000;
    5027        {
    5128                int idx = 0;
     
    11693        }
    11794
    118         USAGE:;
    119         int outfd = fileno(out);
    120         if(isatty(outfd)) {
    121                 struct winsize size;
    122                 int ret = ioctl(outfd, TIOCGWINSZ, &size);
    123                 if(ret < 0) abort( "ioctl error: (%d) %s\n", (int)errno, strerror(errno) );
    124                 max_width = size.ws_col;
    125         }
    126 
    127         fprintf(out, "Usage:\n  %s %s\n", argv[0], usage);
     95        USAGE:
     96        fprintf(out, "%s\n", usage);
    12897
    12998        for(i; opt_count) {
    130                 printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
     99                fprintf(out, "  -%c, --%-*s   %s\n", options[i].short_name, width, options[i].long_name, options[i].help);
    131100        }
    132101        fprintf(out, "  -%c, --%-*s   %s\n", 'h', width, "help", "print this help message");
     
    163132}
    164133
    165 bool parse(const char * arg, unsigned & value) {
    166         char * end;
    167         unsigned long long int r = strtoull(arg, &end, 10);
    168         if(*end != '\0') return false;
    169         if(r > (unsigned)MAX) return false;
    170 
    171         value = r;
    172         return true;
    173 }
    174 
    175 bool parse(const char * arg, size_t & value) {
    176         char * end;
    177         unsigned long long int r = strtoull(arg, &end, 10);
    178         if(*end != '\0') return false;
    179         if(r > (size_t)MAX) return false;
    180 
    181         value = r;
    182         return true;
    183 }
    184 
    185134bool parse(const char * arg, int & value) {
    186135        char * end;
  • benchmark/io/http/parseargs.hfa

    r04b73b6 rf0c3120  
    3838
    3939bool parse(const char *, const char * & );
    40 bool parse(const char *, unsigned & );
    41 bool parse(const char *, size_t & );
    4240bool parse(const char *, int & );
  • benchmark/io/http/protocol.cfa

    r04b73b6 rf0c3120  
    2525};
    2626
    27 _Static_assert( KNOWN_CODES == (sizeof(http_msgs ) / sizeof(http_msgs [0])));
    28 
    29 const int http_codes[] = {
    30         200,
    31         400,
    32         404,
    33         413,
    34         414,
    35 };
    36 
    37 _Static_assert( KNOWN_CODES == (sizeof(http_codes) / sizeof(http_codes[0])));
    38 
    39 int code_val(HttpCode code) {
    40         return http_codes[code];
    41 }
     27_Static_assert( KNOWN_CODES == (sizeof(http_msgs) / sizeof(http_msgs[0])));
    4228
    4329static inline int answer( int fd, const char * it, int len) {
     
    7561        for() {
    7662                int ret = cfa_read(fd, it, count);
    77                 if(ret == 0 ) return [OK200, true, 0p, 0];
    7863                if(ret < 0 ) {
     64                        if( errno ) return [OK200, true, 0p, 0];
    7965                        if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ;
    8066                        abort( "read error: (%d) %s\n", (int)errno, strerror(errno) );
  • benchmark/io/http/protocol.hfa

    r04b73b6 rf0c3120  
    1010};
    1111
    12 int code_val(HttpCode code);
    13 
    1412int answer_error( int fd, HttpCode code );
    1513int answer_header( int fd, size_t size );
  • benchmark/io/http/worker.cfa

    r04b73b6 rf0c3120  
    1212#include "filecache.hfa"
    1313
     14extern "C" {
     15// extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
     16extern ssize_t splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags);
     17}
     18
     19ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count) {
     20        return splice(in_fd, offset, out_fd, 0p, count, 0);
     21}
     22
     23
    1424//=============================================================================================
    1525// Worker Thread
    1626//=============================================================================================
    1727void ?{}( Worker & this ) {
    18         ((thread&)this){ "Server Worker Thread", *options.clopts.instance };
    19         this.pipe[0] = -1;
    20         this.pipe[1] = -1;
     28        ((thread&)this){ "Server Worker Thread", *options.the_cluster };
     29        int ret = pipe(this.pipe);
     30        if( ret < 0 ) { abort( "pipe error: (%d) %s\n", (int)errno, strerror(errno) ); }
    2131}
    2232
    2333void main( Worker & this ) {
    24         park( __cfaabi_dbg_ctx );
    25         /* paranoid */ assert( this.pipe[0] != -1 );
    26         /* paranoid */ assert( this.pipe[1] != -1 );
    27 
    2834        CONNECTION:
    29         for() {
    30                 int fd = take(wait_connect);
    31                 if (fd < 0) break;
    32 
    33                 printf("New connection %d, waiting for requests\n", fd);
     35        while( int fd = take(wait_connect); fd >= 0) {
     36            printf("New connection, waiting for requests\n");
    3437                REQUEST:
    3538                for() {
     
    4043
    4144                        // Read the http request
    42                         size_t len = options.socket.buflen;
     45                        size_t len = 1024;
    4346                        char buffer[len];
    4447                        printf("Reading request\n");
     
    5356                        // If this wasn't a request retrun 400
    5457                        if( code != OK200 ) {
    55                                 printf("Invalid Request : %d\n", code_val(code));
     58                                printf("Invalid Request\n");
    5659                                answer_error(fd, code);
    5760                                continue REQUEST;
    5861                        }
    5962
    60                         printf("Request for file %.*s\n", (int)name_size, file);
     63                        printf("Request for file %.*s\n", name_size, file);
    6164
    6265                        // Get the fd from the file cache
     
    8790//=============================================================================================
    8891void ?{}( Acceptor & this, int sockfd, struct sockaddr * addr, socklen_t * addrlen, int flags ) {
    89         ((thread&)this){ "Acceptor Thread", *options.clopts.instance };
     92        ((thread&)this){ "Acceptor Thread", *options.the_cluster };
    9093        this.sockfd  = sockfd;
    9194        this.addr    = addr;
     
    102105                }
    103106
    104                 printf("New connection accepted\n");
     107            printf("New connection accepted\n");
    105108                put( wait_connect, ret );
    106         }
     109      }
    107110}
  • libcfa/configure

    r04b73b6 rf0c3120  
    20542054
    20552055} # ac_fn_c_check_header_mongrel
    2056 
    2057 # ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
    2058 # ---------------------------------------------
    2059 # Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
    2060 # accordingly.
    2061 ac_fn_c_check_decl ()
    2062 {
    2063   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
    2064   as_decl_name=`echo $2|sed 's/ *(.*//'`
    2065   as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
    2066   { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
    2067 $as_echo_n "checking whether $as_decl_name is declared... " >&6; }
    2068 if eval \${$3+:} false; then :
    2069   $as_echo_n "(cached) " >&6
    2070 else
    2071   cat confdefs.h - <<_ACEOF >conftest.$ac_ext
    2072 /* end confdefs.h.  */
    2073 $4
    2074 int
    2075 main ()
    2076 {
    2077 #ifndef $as_decl_name
    2078 #ifdef __cplusplus
    2079   (void) $as_decl_use;
    2080 #else
    2081   (void) $as_decl_name;
    2082 #endif
    2083 #endif
    2084 
    2085   ;
    2086   return 0;
    2087 }
    2088 _ACEOF
    2089 if ac_fn_c_try_compile "$LINENO"; then :
    2090   eval "$3=yes"
    2091 else
    2092   eval "$3=no"
    2093 fi
    2094 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
    2095 fi
    2096 eval ac_res=\$$3
    2097                { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
    2098 $as_echo "$ac_res" >&6; }
    2099   eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
    2100 
    2101 } # ac_fn_c_check_decl
    21022056cat >config.log <<_ACEOF
    21032057This file contains any messages produced by compilers while
     
    1700816962
    1700916963
    17010 
    17011 
    17012 #io_uring 5.4 and earlier uses defines
    17013 #io_uring 5.5 uses enum values
    17014 #io_uring 5.6 and later uses probes
    17015 
    1701616964for ac_header in linux/io_uring.h
    1701716965do :
     
    1702116969#define HAVE_LINUX_IO_URING_H 1
    1702216970_ACEOF
    17023 
    17024         $as_echo "#define CFA_HAVE_LINUX_IO_URING_H 1" >>confdefs.h
    17025 
    17026         # AC_CHECK_HEADER([liburing.h], [
    17027         #       AC_CHECK_LIB([uring], [io_uring_get_probe])
    17028         # ])
    17029 
    17030                 ac_fn_c_check_decl "$LINENO" "IORING_OP_NOP" "ac_cv_have_decl_IORING_OP_NOP" "#include <linux/io_uring.h>
    17031 "
    17032 if test "x$ac_cv_have_decl_IORING_OP_NOP" = xyes; then :
    17033   $as_echo "#define CFA_HAVE_IORING_OP_NOP 1" >>confdefs.h
    17034 
    17035 fi
    17036 
    17037 
    17038                 ac_fn_c_check_decl "$LINENO" "IORING_OP_READV" "ac_cv_have_decl_IORING_OP_READV" "#include <linux/io_uring.h>
    17039 "
    17040 if test "x$ac_cv_have_decl_IORING_OP_READV" = xyes; then :
    17041   $as_echo "#define CFA_HAVE_IORING_OP_READV 1" >>confdefs.h
    17042 
    17043 fi
    17044 
    17045 
    17046                 ac_fn_c_check_decl "$LINENO" "IORING_OP_WRITEV" "ac_cv_have_decl_IORING_OP_WRITEV" "#include <linux/io_uring.h>
    17047 "
    17048 if test "x$ac_cv_have_decl_IORING_OP_WRITEV" = xyes; then :
    17049   $as_echo "#define CFA_HAVE_IORING_OP_WRITEV 1" >>confdefs.h
    17050 
    17051 fi
    17052 
    17053 
    17054                 ac_fn_c_check_decl "$LINENO" "IORING_OP_FSYNC" "ac_cv_have_decl_IORING_OP_FSYNC" "#include <linux/io_uring.h>
    17055 "
    17056 if test "x$ac_cv_have_decl_IORING_OP_FSYNC" = xyes; then :
    17057   $as_echo "#define CFA_HAVE_IORING_OP_FSYNC 1" >>confdefs.h
    17058 
    17059 fi
    17060 
    17061 
    17062                 ac_fn_c_check_decl "$LINENO" "IORING_OP_READ_FIXED" "ac_cv_have_decl_IORING_OP_READ_FIXED" "#include <linux/io_uring.h>
    17063 "
    17064 if test "x$ac_cv_have_decl_IORING_OP_READ_FIXED" = xyes; then :
    17065   $as_echo "#define CFA_HAVE_IORING_OP_READ_FIXED 1" >>confdefs.h
    17066 
    17067 fi
    17068 
    17069 
    17070                 ac_fn_c_check_decl "$LINENO" "IORING_OP_WRITE_FIXED" "ac_cv_have_decl_IORING_OP_WRITE_FIXED" "#include <linux/io_uring.h>
    17071 "
    17072 if test "x$ac_cv_have_decl_IORING_OP_WRITE_FIXED" = xyes; then :
    17073   $as_echo "#define CFA_HAVE_IORING_OP_WRITE_FIXED 1" >>confdefs.h
    17074 
    17075 fi
    17076 
    17077 
    17078                 ac_fn_c_check_decl "$LINENO" "IORING_OP_POLL_ADD" "ac_cv_have_decl_IORING_OP_POLL_ADD" "#include <linux/io_uring.h>
    17079 "
    17080 if test "x$ac_cv_have_decl_IORING_OP_POLL_ADD" = xyes; then :
    17081   $as_echo "#define CFA_HAVE_IORING_OP_POLL_ADD 1" >>confdefs.h
    17082 
    17083 fi
    17084 
    17085 
    17086                 ac_fn_c_check_decl "$LINENO" "IORING_OP_POLL_REMOVE" "ac_cv_have_decl_IORING_OP_POLL_REMOVE" "#include <linux/io_uring.h>
    17087 "
    17088 if test "x$ac_cv_have_decl_IORING_OP_POLL_REMOVE" = xyes; then :
    17089   $as_echo "#define CFA_HAVE_IORING_OP_POLL_REMOVE 1" >>confdefs.h
    17090 
    17091 fi
    17092 
    17093 
    17094                 ac_fn_c_check_decl "$LINENO" "IORING_OP_SYNC_FILE_RANGE" "ac_cv_have_decl_IORING_OP_SYNC_FILE_RANGE" "#include <linux/io_uring.h>
    17095 "
    17096 if test "x$ac_cv_have_decl_IORING_OP_SYNC_FILE_RANGE" = xyes; then :
    17097   $as_echo "#define CFA_HAVE_IORING_OP_SYNC_FILE_RANGE 1" >>confdefs.h
    17098 
    17099 fi
    17100 
    17101 
    17102                 ac_fn_c_check_decl "$LINENO" "IORING_OP_SENDMSG" "ac_cv_have_decl_IORING_OP_SENDMSG" "#include <linux/io_uring.h>
    17103 "
    17104 if test "x$ac_cv_have_decl_IORING_OP_SENDMSG" = xyes; then :
    17105   $as_echo "#define CFA_HAVE_IORING_OP_SENDMSG 1" >>confdefs.h
    17106 
    17107 fi
    17108 
    17109 
    17110                 ac_fn_c_check_decl "$LINENO" "IORING_OP_RECVMSG" "ac_cv_have_decl_IORING_OP_RECVMSG" "#include <linux/io_uring.h>
    17111 "
    17112 if test "x$ac_cv_have_decl_IORING_OP_RECVMSG" = xyes; then :
    17113   $as_echo "#define CFA_HAVE_IORING_OP_RECVMSG 1" >>confdefs.h
    17114 
    17115 fi
    17116 
    17117 
    17118                 ac_fn_c_check_decl "$LINENO" "IORING_OP_TIMEOUT" "ac_cv_have_decl_IORING_OP_TIMEOUT" "#include <linux/io_uring.h>
    17119 "
    17120 if test "x$ac_cv_have_decl_IORING_OP_TIMEOUT" = xyes; then :
    17121   $as_echo "#define CFA_HAVE_IORING_OP_TIMEOUT 1" >>confdefs.h
    17122 
    17123 fi
    17124 
    17125 
    17126                 ac_fn_c_check_decl "$LINENO" "IORING_OP_TIMEOUT_REMOVE" "ac_cv_have_decl_IORING_OP_TIMEOUT_REMOVE" "#include <linux/io_uring.h>
    17127 "
    17128 if test "x$ac_cv_have_decl_IORING_OP_TIMEOUT_REMOVE" = xyes; then :
    17129   $as_echo "#define CFA_HAVE_IORING_OP_TIMEOUT_REMOVE 1" >>confdefs.h
    17130 
    17131 fi
    17132 
    17133 
    17134                 ac_fn_c_check_decl "$LINENO" "IORING_OP_ACCEPT" "ac_cv_have_decl_IORING_OP_ACCEPT" "#include <linux/io_uring.h>
    17135 "
    17136 if test "x$ac_cv_have_decl_IORING_OP_ACCEPT" = xyes; then :
    17137   $as_echo "#define CFA_HAVE_IORING_OP_ACCEPT 1" >>confdefs.h
    17138 
    17139 fi
    17140 
    17141 
    17142                 ac_fn_c_check_decl "$LINENO" "IORING_OP_ASYNC_CANCEL" "ac_cv_have_decl_IORING_OP_ASYNC_CANCEL" "#include <linux/io_uring.h>
    17143 "
    17144 if test "x$ac_cv_have_decl_IORING_OP_ASYNC_CANCEL" = xyes; then :
    17145   $as_echo "#define CFA_HAVE_IORING_OP_ASYNC_CANCEL 1" >>confdefs.h
    17146 
    17147 fi
    17148 
    17149 
    17150                 ac_fn_c_check_decl "$LINENO" "IORING_OP_LINK_TIMEOUT" "ac_cv_have_decl_IORING_OP_LINK_TIMEOUT" "#include <linux/io_uring.h>
    17151 "
    17152 if test "x$ac_cv_have_decl_IORING_OP_LINK_TIMEOUT" = xyes; then :
    17153   $as_echo "#define CFA_HAVE_IORING_OP_LINK_TIMEOUT 1" >>confdefs.h
    17154 
    17155 fi
    17156 
    17157 
    17158                 ac_fn_c_check_decl "$LINENO" "IORING_OP_CONNECT" "ac_cv_have_decl_IORING_OP_CONNECT" "#include <linux/io_uring.h>
    17159 "
    17160 if test "x$ac_cv_have_decl_IORING_OP_CONNECT" = xyes; then :
    17161   $as_echo "#define CFA_HAVE_IORING_OP_CONNECT 1" >>confdefs.h
    17162 
    17163 fi
    17164 
    17165 
    17166                 ac_fn_c_check_decl "$LINENO" "IORING_OP_FALLOCATE" "ac_cv_have_decl_IORING_OP_FALLOCATE" "#include <linux/io_uring.h>
    17167 "
    17168 if test "x$ac_cv_have_decl_IORING_OP_FALLOCATE" = xyes; then :
    17169   $as_echo "#define CFA_HAVE_IORING_OP_FALLOCATE 1" >>confdefs.h
    17170 
    17171 fi
    17172 
    17173 
    17174                 ac_fn_c_check_decl "$LINENO" "IORING_OP_OPENAT" "ac_cv_have_decl_IORING_OP_OPENAT" "#include <linux/io_uring.h>
    17175 "
    17176 if test "x$ac_cv_have_decl_IORING_OP_OPENAT" = xyes; then :
    17177   $as_echo "#define CFA_HAVE_IORING_OP_OPENAT 1" >>confdefs.h
    17178 
    17179 fi
    17180 
    17181 
    17182                 ac_fn_c_check_decl "$LINENO" "IORING_OP_CLOSE" "ac_cv_have_decl_IORING_OP_CLOSE" "#include <linux/io_uring.h>
    17183 "
    17184 if test "x$ac_cv_have_decl_IORING_OP_CLOSE" = xyes; then :
    17185   $as_echo "#define CFA_HAVE_IORING_OP_CLOSE 1" >>confdefs.h
    17186 
    17187 fi
    17188 
    17189 
    17190                 ac_fn_c_check_decl "$LINENO" "IORING_OP_FILES_UPDATE" "ac_cv_have_decl_IORING_OP_FILES_UPDATE" "#include <linux/io_uring.h>
    17191 "
    17192 if test "x$ac_cv_have_decl_IORING_OP_FILES_UPDATE" = xyes; then :
    17193   $as_echo "#define CFA_HAVE_IORING_OP_FILES_UPDATE 1" >>confdefs.h
    17194 
    17195 fi
    17196 
    17197 
    17198                 ac_fn_c_check_decl "$LINENO" "IORING_OP_STATX" "ac_cv_have_decl_IORING_OP_STATX" "#include <linux/io_uring.h>
    17199 "
    17200 if test "x$ac_cv_have_decl_IORING_OP_STATX" = xyes; then :
    17201   $as_echo "#define CFA_HAVE_IORING_OP_STATX 1" >>confdefs.h
    17202 
    17203 fi
    17204 
    17205 
    17206                 ac_fn_c_check_decl "$LINENO" "IORING_OP_READ" "ac_cv_have_decl_IORING_OP_READ" "#include <linux/io_uring.h>
    17207 "
    17208 if test "x$ac_cv_have_decl_IORING_OP_READ" = xyes; then :
    17209   $as_echo "#define CFA_HAVE_IORING_OP_READ 1" >>confdefs.h
    17210 
    17211 fi
    17212 
    17213 
    17214                 ac_fn_c_check_decl "$LINENO" "IORING_OP_WRITE" "ac_cv_have_decl_IORING_OP_WRITE" "#include <linux/io_uring.h>
    17215 "
    17216 if test "x$ac_cv_have_decl_IORING_OP_WRITE" = xyes; then :
    17217   $as_echo "#define CFA_HAVE_IORING_OP_WRITE 1" >>confdefs.h
    17218 
    17219 fi
    17220 
    17221 
    17222                 ac_fn_c_check_decl "$LINENO" "IORING_OP_FADVISE" "ac_cv_have_decl_IORING_OP_FADVISE" "#include <linux/io_uring.h>
    17223 "
    17224 if test "x$ac_cv_have_decl_IORING_OP_FADVISE" = xyes; then :
    17225   $as_echo "#define CFA_HAVE_IORING_OP_FADVISE 1" >>confdefs.h
    17226 
    17227 fi
    17228 
    17229 
    17230                 ac_fn_c_check_decl "$LINENO" "IORING_OP_MADVISE" "ac_cv_have_decl_IORING_OP_MADVISE" "#include <linux/io_uring.h>
    17231 "
    17232 if test "x$ac_cv_have_decl_IORING_OP_MADVISE" = xyes; then :
    17233   $as_echo "#define CFA_HAVE_IORING_OP_MADVISE 1" >>confdefs.h
    17234 
    17235 fi
    17236 
    17237 
    17238                 ac_fn_c_check_decl "$LINENO" "IORING_OP_SEND" "ac_cv_have_decl_IORING_OP_SEND" "#include <linux/io_uring.h>
    17239 "
    17240 if test "x$ac_cv_have_decl_IORING_OP_SEND" = xyes; then :
    17241   $as_echo "#define CFA_HAVE_IORING_OP_SEND 1" >>confdefs.h
    17242 
    17243 fi
    17244 
    17245 
    17246                 ac_fn_c_check_decl "$LINENO" "IORING_OP_RECV" "ac_cv_have_decl_IORING_OP_RECV" "#include <linux/io_uring.h>
    17247 "
    17248 if test "x$ac_cv_have_decl_IORING_OP_RECV" = xyes; then :
    17249   $as_echo "#define CFA_HAVE_IORING_OP_RECV 1" >>confdefs.h
    17250 
    17251 fi
    17252 
    17253 
    17254                 ac_fn_c_check_decl "$LINENO" "IORING_OP_OPENAT2" "ac_cv_have_decl_IORING_OP_OPENAT2" "#include <linux/io_uring.h>
    17255 "
    17256 if test "x$ac_cv_have_decl_IORING_OP_OPENAT2" = xyes; then :
    17257   $as_echo "#define CFA_HAVE_IORING_OP_OPENAT2 1" >>confdefs.h
    17258 
    17259 fi
    17260 
    17261 
    17262                 ac_fn_c_check_decl "$LINENO" "IORING_OP_EPOLL_CTL" "ac_cv_have_decl_IORING_OP_EPOLL_CTL" "#include <linux/io_uring.h>
    17263 "
    17264 if test "x$ac_cv_have_decl_IORING_OP_EPOLL_CTL" = xyes; then :
    17265   $as_echo "#define CFA_HAVE_IORING_OP_EPOLL_CTL 1" >>confdefs.h
    17266 
    17267 fi
    17268 
    17269 
    17270                 ac_fn_c_check_decl "$LINENO" "IORING_OP_SPLICE" "ac_cv_have_decl_IORING_OP_SPLICE" "#include <linux/io_uring.h>
    17271 "
    17272 if test "x$ac_cv_have_decl_IORING_OP_SPLICE" = xyes; then :
    17273   $as_echo "#define CFA_HAVE_IORING_OP_SPLICE 1" >>confdefs.h
    17274 
    17275 fi
    17276 
    17277 
    17278                 ac_fn_c_check_decl "$LINENO" "IORING_OP_PROVIDE_BUFFERS" "ac_cv_have_decl_IORING_OP_PROVIDE_BUFFERS" "#include <linux/io_uring.h>
    17279 "
    17280 if test "x$ac_cv_have_decl_IORING_OP_PROVIDE_BUFFERS" = xyes; then :
    17281   $as_echo "#define CFA_HAVE_IORING_OP_PROVIDE_BUFFERS 1" >>confdefs.h
    17282 
    17283 fi
    17284 
    17285 
    17286                 ac_fn_c_check_decl "$LINENO" "IORING_OP_REMOVE_BUFFER" "ac_cv_have_decl_IORING_OP_REMOVE_BUFFER" "#include <linux/io_uring.h>
    17287 "
    17288 if test "x$ac_cv_have_decl_IORING_OP_REMOVE_BUFFER" = xyes; then :
    17289   $as_echo "#define CFA_HAVE_IORING_OP_REMOVE_BUFFER 1" >>confdefs.h
    17290 
    17291 fi
    17292 
    17293 
    1729416971
    1729516972fi
  • libcfa/configure.ac

    r04b73b6 rf0c3120  
    123123AC_PROG_MAKE_SET
    124124
    125 
    126 
    127 #io_uring 5.4 and earlier uses defines
    128 #io_uring 5.5 uses enum values
    129 #io_uring 5.6 and later uses probes
    130 
    131 AC_CHECK_HEADERS([linux/io_uring.h], [
    132         AC_DEFINE(CFA_HAVE_LINUX_IO_URING_H)
    133         # AC_CHECK_HEADER([liburing.h], [
    134         #       AC_CHECK_LIB([uring], [io_uring_get_probe])
    135         # ])
    136         m4_foreach([op], [IORING_OP_NOP,IORING_OP_READV,IORING_OP_WRITEV,IORING_OP_FSYNC,IORING_OP_READ_FIXED,IORING_OP_WRITE_FIXED,IORING_OP_POLL_ADD,IORING_OP_POLL_REMOVE,IORING_OP_SYNC_FILE_RANGE,IORING_OP_SENDMSG,IORING_OP_RECVMSG,IORING_OP_TIMEOUT,IORING_OP_TIMEOUT_REMOVE,IORING_OP_ACCEPT,IORING_OP_ASYNC_CANCEL,IORING_OP_LINK_TIMEOUT,IORING_OP_CONNECT,IORING_OP_FALLOCATE,IORING_OP_OPENAT,IORING_OP_CLOSE,IORING_OP_FILES_UPDATE,IORING_OP_STATX,IORING_OP_READ,IORING_OP_WRITE,IORING_OP_FADVISE,IORING_OP_MADVISE,IORING_OP_SEND,IORING_OP_RECV,IORING_OP_OPENAT2,IORING_OP_EPOLL_CTL,IORING_OP_SPLICE,IORING_OP_PROVIDE_BUFFERS,IORING_OP_REMOVE_BUFFER], [
    137                 AC_CHECK_DECL(op, [AC_DEFINE([CFA_HAVE_]op)], [], [[#include <linux/io_uring.h>]])
    138         ])
    139 ])
     125AC_CHECK_HEADERS([linux/io_uring.h])
    140126AC_CHECK_FUNCS([preadv2 pwritev2])
    141127
  • libcfa/prelude/defines.hfa.in

    r04b73b6 rf0c3120  
    1414//
    1515
    16 #undef CFA_HAVE_LINUX_IO_URING_H
    17 
    18 #undef CFA_HAVE_IORING_OP_NOP
    19 #undef CFA_HAVE_IORING_OP_READV
    20 #undef CFA_HAVE_IORING_OP_WRITEV
    21 #undef CFA_HAVE_IORING_OP_FSYNC
    22 #undef CFA_HAVE_IORING_OP_READ_FIXED
    23 #undef CFA_HAVE_IORING_OP_WRITE_FIXED
    24 #undef CFA_HAVE_IORING_OP_POLL_ADD
    25 #undef CFA_HAVE_IORING_OP_POLL_REMOVE
    26 #undef CFA_HAVE_IORING_OP_SYNC_FILE_RANGE
    27 #undef CFA_HAVE_IORING_OP_SENDMSG
    28 #undef CFA_HAVE_IORING_OP_RECVMSG
    29 #undef CFA_HAVE_IORING_OP_TIMEOUT
    30 #undef CFA_HAVE_IORING_OP_TIMEOUT_REMOVE
    31 #undef CFA_HAVE_IORING_OP_ACCEPT
    32 #undef CFA_HAVE_IORING_OP_ASYNC_CANCEL
    33 #undef CFA_HAVE_IORING_OP_LINK_TIMEOUT
    34 #undef CFA_HAVE_IORING_OP_CONNECT
    35 #undef CFA_HAVE_IORING_OP_FALLOCATE
    36 #undef CFA_HAVE_IORING_OP_OPENAT
    37 #undef CFA_HAVE_IORING_OP_CLOSE
    38 #undef CFA_HAVE_IORING_OP_FILES_UPDATE
    39 #undef CFA_HAVE_IORING_OP_STATX
    40 #undef CFA_HAVE_IORING_OP_READ
    41 #undef CFA_HAVE_IORING_OP_WRITE
    42 #undef CFA_HAVE_IORING_OP_FADVISE
    43 #undef CFA_HAVE_IORING_OP_MADVISE
    44 #undef CFA_HAVE_IORING_OP_SEND
    45 #undef CFA_HAVE_IORING_OP_RECV
    46 #undef CFA_HAVE_IORING_OP_OPENAT2
    47 #undef CFA_HAVE_IORING_OP_EPOLL_CTL
    48 #undef CFA_HAVE_IORING_OP_SPLICE
    49 #undef CFA_HAVE_IORING_OP_PROVIDE_BUFFERS
    50 #undef CFA_HAVE_IORING_OP_REMOVE_BUFFER
     16#undef HAVE_LINUX_IO_URING_H
    5117
    5218#undef HAVE_PREADV2
  • libcfa/src/concurrency/io.cfa

    r04b73b6 rf0c3120  
    1616#if defined(__CFA_DEBUG__)
    1717        // #define __CFA_DEBUG_PRINT_IO__
    18         // #define __CFA_DEBUG_PRINT_IO_CORE__
     18        #define __CFA_DEBUG_PRINT_IO_CORE__
    1919#endif
    2020
     
    2222#include "bitmanip.hfa"
    2323
    24 #if !defined(CFA_HAVE_LINUX_IO_URING_H)
     24#if !defined(HAVE_LINUX_IO_URING_H)
    2525        void __kernel_io_startup( cluster &, unsigned, bool ) {
    2626                // Nothing to do without io_uring
     
    490490        static uint32_t __release_consumed_submission( struct __io_data & ring );
    491491
    492         static inline void process(struct io_uring_cqe & cqe, struct __processor_id_t * id ) {
    493                 struct __io_user_data_t * data = (struct __io_user_data_t *)(uintptr_t)cqe.user_data;
    494                 __cfadbg_print_safe( io, "Kernel I/O : Syscall completed : cqe %p, result %d for %p\n", data, cqe.res, data->thrd );
    495 
    496                 data->result = cqe.res;
    497                 if(!id) { unpark(     data->thrd __cfaabi_dbg_ctx2 ); }
    498                 else  { __unpark( id, data->thrd __cfaabi_dbg_ctx2 ); }
    499         }
    500 
    501492        // Process a single completion message from the io_uring
    502493        // This is NOT thread-safe
     
    547538                        /* paranoid */ verify(&cqe);
    548539
    549                         process( cqe, !mask ? (struct __processor_id_t *)0p : &ring.poller.slow.id );
     540                        struct __io_user_data_t * data = (struct __io_user_data_t *)(uintptr_t)cqe.user_data;
     541                        __cfadbg_print_safe( io, "Kernel I/O : Performed reading io cqe %p, result %d for %p\n", data, cqe.res, data->thrd );
     542
     543                        data->result = cqe.res;
     544                        if(!mask) { unpark( data->thrd __cfaabi_dbg_ctx2 ); }
     545                        else      { __unpark( &ring.poller.slow.id, data->thrd __cfaabi_dbg_ctx2 ); }
    550546                }
    551547
  • libcfa/src/concurrency/iocall.cfa

    r04b73b6 rf0c3120  
    2020//=============================================================================================
    2121
    22 #if defined(CFA_HAVE_LINUX_IO_URING_H)
     22#if defined(HAVE_LINUX_IO_URING_H)
    2323        #include <stdint.h>
    2424        #include <linux/io_uring.h>
     
    122122#if defined(HAVE_PREADV2)
    123123        ssize_t cfa_preadv2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    124                 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READV)
     124                #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)
    125125                        return preadv2(fd, iov, iovcnt, offset, flags);
    126126                #else
     
    134134
    135135        ssize_t cfa_preadv2_fixed(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    136                 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READV)
     136                #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READV)
    137137                        return preadv2(fd, iov, iovcnt, offset, flags);
    138138                #else
     
    149149#if defined(HAVE_PWRITEV2)
    150150        ssize_t cfa_pwritev2(int fd, const struct iovec *iov, int iovcnt, off_t offset, int flags) {
    151                 #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_WRITEV)
     151                #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITEV)
    152152                        return pwritev2(fd, iov, iovcnt, offset, flags);
    153153                #else
     
    162162
    163163int cfa_fsync(int fd) {
    164         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FSYNC)
     164        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FSYNC)
    165165                return fsync(fd);
    166166        #else
     
    174174
    175175int cfa_sync_file_range(int fd, int64_t offset, int64_t nbytes, unsigned int flags) {
    176         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SYNC_FILE_RANGE)
     176        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SYNC_FILE_RANGE)
    177177                return sync_file_range(fd, offset, nbytes, flags);
    178178        #else
     
    190190
    191191ssize_t cfa_sendmsg(int sockfd, const struct msghdr *msg, int flags) {
    192         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SENDMSG)
     192        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SENDMSG)
    193193                return sendmsg(sockfd, msg, flags);
    194194        #else
     
    203203
    204204ssize_t cfa_recvmsg(int sockfd, struct msghdr *msg, int flags) {
    205         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_RECVMSG)
     205        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECVMSG)
    206206                return recvmsg(sockfd, msg, flags);
    207207        #else
     
    216216
    217217ssize_t cfa_send(int sockfd, const void *buf, size_t len, int flags) {
    218         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SEND)
     218        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SEND)
    219219                return send( sockfd, buf, len, flags );
    220220        #else
     
    231231
    232232ssize_t cfa_recv(int sockfd, void *buf, size_t len, int flags) {
    233         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_RECV)
     233        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_RECV)
    234234                return recv( sockfd, buf, len, flags );
    235235        #else
     
    246246
    247247int cfa_accept4(int sockfd, struct sockaddr *addr, socklen_t *addrlen, int flags) {
    248         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_ACCEPT)
     248        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_ACCEPT)
    249249                return accept4( sockfd, addr, addrlen, flags );
    250250        #else
     
    261261
    262262int cfa_connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen) {
    263         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_CONNECT)
     263        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CONNECT)
    264264                return connect( sockfd, addr, addrlen );
    265265        #else
     
    275275
    276276int cfa_fallocate(int fd, int mode, uint64_t offset, uint64_t len) {
    277         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FALLOCATE)
     277        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FALLOCATE)
    278278                return fallocate( fd, mode, offset, len );
    279279        #else
     
    290290
    291291int cfa_fadvise(int fd, uint64_t offset, uint64_t len, int advice) {
    292         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_FADVISE)
     292        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_FADVISE)
    293293                return posix_fadvise( fd, offset, len, advice );
    294294        #else
     
    305305
    306306int cfa_madvise(void *addr, size_t length, int advice) {
    307         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_MADVISE)
     307        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_MADVISE)
    308308                return madvise( addr, length, advice );
    309309        #else
     
    320320
    321321int cfa_openat(int dirfd, const char *pathname, int flags, mode_t mode) {
    322         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_OPENAT)
     322        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_OPENAT)
    323323                return openat( dirfd, pathname, flags, mode );
    324324        #else
     
    335335
    336336int cfa_close(int fd) {
    337         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_CLOSE)
     337        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_CLOSE)
    338338                return close( fd );
    339339        #else
     
    349349struct statx;
    350350int cfa_statx(int dirfd, const char *pathname, int flags, unsigned int mask, struct statx *statxbuf) {
    351         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_STATX)
     351        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_STATX)
    352352                #if defined(__NR_statx)
    353353                        return syscall( __NR_statx, dirfd, pathname, flags, mask, statxbuf );
     
    367367
    368368ssize_t cfa_read(int fd, void *buf, size_t count) {
    369         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_READ)
     369        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_READ)
    370370                return read( fd, buf, count );
    371371        #else
     
    379379
    380380ssize_t cfa_write(int fd, void *buf, size_t count) {
    381         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_WRITE)
     381        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_WRITE)
    382382                return read( fd, buf, count );
    383383        #else
     
    391391
    392392ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags) {
    393         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SPLICE)
     393        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_SPLICE)
    394394                return splice( fd_in, off_in, fd_out, off_out, len, flags );
    395395        #else
     
    405405}
    406406
    407 ssize_t cfa_splice(int fd_in, loff_t *off_in, int fd_out, loff_t *off_out, size_t len, unsigned int flags, int in_flags, int out_flags) {
    408         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_SPLICE)
    409                 return splice( fd_in, off_in, fd_out, off_out, len, flags );
    410         #else
    411                 __submit_prelude
    412 
    413                 (*sqe){ IORING_OP_SPLICE, fd_out, 0p, len, off_out };
    414                 sqe->splice_fd_in  = fd_in;
    415                 sqe->splice_off_in = off_in;
    416                 sqe->splice_flags  = flags | out_flags;
    417                 sqe->flags = in_flags;
    418 
    419                 __submit_wait
    420         #endif
    421 }
    422 
    423407ssize_t cfa_tee(int fd_in, int fd_out, size_t len, unsigned int flags) {
    424         #if !defined(CFA_HAVE_LINUX_IO_URING_H) || !defined(CFA_HAVE_IORING_OP_TEE)
     408        #if !defined(HAVE_LINUX_IO_URING_H) || !defined(IORING_OP_TEE)
    425409                return tee( fd_in, fd_out, len, flags );
    426410        #else
     
    445429
    446430bool has_user_level_blocking( fptr_t func ) {
    447         #if defined(CFA_HAVE_LINUX_IO_URING_H)
     431        #if defined(HAVE_LINUX_IO_URING_H)
    448432                #if defined(HAVE_PREADV2)
    449433                        if( /*func == (fptr_t)preadv2 || */
    450434                                func == (fptr_t)cfa_preadv2 )
    451                                 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_READV ,
    452                                 return IS_DEFINED(CFA_HAVE_IORING_OP_READV);
     435                                #define _CFA_IO_FEATURE_IORING_OP_READV ,
     436                                return IS_DEFINED(IORING_OP_READV);
    453437                #endif
    454438
     
    456440                        if( /*func == (fptr_t)pwritev2 || */
    457441                                func == (fptr_t)cfa_pwritev2 )
    458                                 #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_WRITEV ,
    459                                 return IS_DEFINED(CFA_HAVE_IORING_OP_WRITEV);
     442                                #define _CFA_IO_FEATURE_IORING_OP_WRITEV ,
     443                                return IS_DEFINED(IORING_OP_WRITEV);
    460444                #endif
    461445
    462446                if( /*func == (fptr_t)fsync || */
    463447                        func == (fptr_t)cfa_fsync )
    464                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FSYNC ,
    465                         return IS_DEFINED(CFA_HAVE_IORING_OP_FSYNC);
     448                        #define _CFA_IO_FEATURE_IORING_OP_FSYNC ,
     449                        return IS_DEFINED(IORING_OP_FSYNC);
    466450
    467451                if( /*func == (fptr_t)ync_file_range || */
    468452                        func == (fptr_t)cfa_sync_file_range )
    469                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SYNC_FILE_RANGE ,
    470                         return IS_DEFINED(CFA_HAVE_IORING_OP_SYNC_FILE_RANGE);
     453                        #define _CFA_IO_FEATURE_IORING_OP_SYNC_FILE_RANGE ,
     454                        return IS_DEFINED(IORING_OP_SYNC_FILE_RANGE);
    471455
    472456                if( /*func == (fptr_t)sendmsg || */
    473457                        func == (fptr_t)cfa_sendmsg )
    474                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SENDMSG ,
    475                         return IS_DEFINED(CFA_HAVE_IORING_OP_SENDMSG);
     458                        #define _CFA_IO_FEATURE_IORING_OP_SENDMSG ,
     459                        return IS_DEFINED(IORING_OP_SENDMSG);
    476460
    477461                if( /*func == (fptr_t)recvmsg || */
    478462                        func == (fptr_t)cfa_recvmsg )
    479                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_RECVMSG ,
    480                         return IS_DEFINED(CFA_HAVE_IORING_OP_RECVMSG);
     463                        #define _CFA_IO_FEATURE_IORING_OP_RECVMSG ,
     464                        return IS_DEFINED(IORING_OP_RECVMSG);
    481465
    482466                if( /*func == (fptr_t)send || */
    483467                        func == (fptr_t)cfa_send )
    484                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SEND ,
    485                         return IS_DEFINED(CFA_HAVE_IORING_OP_SEND);
     468                        #define _CFA_IO_FEATURE_IORING_OP_SEND ,
     469                        return IS_DEFINED(IORING_OP_SEND);
    486470
    487471                if( /*func == (fptr_t)recv || */
    488472                        func == (fptr_t)cfa_recv )
    489                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_RECV ,
    490                         return IS_DEFINED(CFA_HAVE_IORING_OP_RECV);
     473                        #define _CFA_IO_FEATURE_IORING_OP_RECV ,
     474                        return IS_DEFINED(IORING_OP_RECV);
    491475
    492476                if( /*func == (fptr_t)accept4 || */
    493477                        func == (fptr_t)cfa_accept4 )
    494                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_ACCEPT ,
    495                         return IS_DEFINED(CFA_HAVE_IORING_OP_ACCEPT);
     478                        #define _CFA_IO_FEATURE_IORING_OP_ACCEPT ,
     479                        return IS_DEFINED(IORING_OP_ACCEPT);
    496480
    497481                if( /*func == (fptr_t)connect || */
    498482                        func == (fptr_t)cfa_connect )
    499                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_CONNECT ,
    500                         return IS_DEFINED(CFA_HAVE_IORING_OP_CONNECT);
     483                        #define _CFA_IO_FEATURE_IORING_OP_CONNECT ,
     484                        return IS_DEFINED(IORING_OP_CONNECT);
    501485
    502486                if( /*func == (fptr_t)fallocate || */
    503487                        func == (fptr_t)cfa_fallocate )
    504                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FALLOCATE ,
    505                         return IS_DEFINED(CFA_HAVE_IORING_OP_FALLOCATE);
     488                        #define _CFA_IO_FEATURE_IORING_OP_FALLOCATE ,
     489                        return IS_DEFINED(IORING_OP_FALLOCATE);
    506490
    507491                if( /*func == (fptr_t)posix_fadvise || */
    508492                        func == (fptr_t)cfa_fadvise )
    509                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_FADVISE ,
    510                         return IS_DEFINED(CFA_HAVE_IORING_OP_FADVISE);
     493                        #define _CFA_IO_FEATURE_IORING_OP_FADVISE ,
     494                        return IS_DEFINED(IORING_OP_FADVISE);
    511495
    512496                if( /*func == (fptr_t)madvise || */
    513497                        func == (fptr_t)cfa_madvise )
    514                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_MADVISE ,
    515                         return IS_DEFINED(CFA_HAVE_IORING_OP_MADVISE);
     498                        #define _CFA_IO_FEATURE_IORING_OP_MADVISE ,
     499                        return IS_DEFINED(IORING_OP_MADVISE);
    516500
    517501                if( /*func == (fptr_t)openat || */
    518502                        func == (fptr_t)cfa_openat )
    519                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_OPENAT ,
    520                         return IS_DEFINED(CFA_HAVE_IORING_OP_OPENAT);
     503                        #define _CFA_IO_FEATURE_IORING_OP_OPENAT ,
     504                        return IS_DEFINED(IORING_OP_OPENAT);
    521505
    522506                if( /*func == (fptr_t)close || */
    523507                        func == (fptr_t)cfa_close )
    524                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_CLOSE ,
    525                         return IS_DEFINED(CFA_HAVE_IORING_OP_CLOSE);
     508                        #define _CFA_IO_FEATURE_IORING_OP_CLOSE ,
     509                        return IS_DEFINED(IORING_OP_CLOSE);
    526510
    527511                if( /*func == (fptr_t)read || */
    528512                        func == (fptr_t)cfa_read )
    529                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_READ ,
    530                         return IS_DEFINED(CFA_HAVE_IORING_OP_READ);
     513                        #define _CFA_IO_FEATURE_IORING_OP_READ ,
     514                        return IS_DEFINED(IORING_OP_READ);
    531515
    532516                if( /*func == (fptr_t)write || */
    533517                        func == (fptr_t)cfa_write )
    534                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_WRITE ,
    535                         return IS_DEFINED(CFA_HAVE_IORING_OP_WRITE);
     518                        #define _CFA_IO_FEATURE_IORING_OP_WRITE ,
     519                        return IS_DEFINED(IORING_OP_WRITE);
    536520
    537521                if( /*func == (fptr_t)splice || */
    538                         func == (fptr_t)(ssize_t (*)(int, loff_t *, int, loff_t *, size_t, unsigned int))cfa_splice,
    539                         func == (fptr_t)(ssize_t (*)(int, loff_t *, int, loff_t *, size_t, unsigned int, int, int))cfa_splice )
    540                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_SPLICE ,
    541                         return IS_DEFINED(CFA_HAVE_IORING_OP_SPLICE);
     522                        func == (fptr_t)cfa_splice )
     523                        #define _CFA_IO_FEATURE_IORING_OP_SPLICE ,
     524                        return IS_DEFINED(IORING_OP_SPLICE);
    542525
    543526                if( /*func == (fptr_t)tee || */
    544527                        func == (fptr_t)cfa_tee )
    545                         #define _CFA_IO_FEATURE_CFA_HAVE_IORING_OP_TEE ,
    546                         return IS_DEFINED(CFA_HAVE_IORING_OP_TEE);
     528                        #define _CFA_IO_FEATURE_IORING_OP_TEE ,
     529                        return IS_DEFINED(IORING_OP_TEE);
    547530        #endif
    548531
  • libcfa/src/concurrency/kernel.cfa

    r04b73b6 rf0c3120  
    228228static void * __invoke_processor(void * arg);
    229229
    230 static init(processor & this, const char name[], cluster & _cltr) with( this ) {
     230void ?{}(processor & this, const char name[], cluster & _cltr) with( this ) {
    231231        this.name = name;
    232232        this.cltr = &_cltr;
    233233        id = -1u;
     234        terminated{ 0 };
    234235        destroyer = 0p;
    235236        do_terminate = false;
    236237        preemption_alarm = 0p;
    237238        pending_preemption = false;
     239        runner.proc = &this;
    238240
    239241        #if !defined(__CFA_NO_STATISTICS__)
     
    242244        #endif
    243245
     246        idle{};
     247
     248        __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
     249
     250        this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    244251        __atomic_fetch_add( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
    245252
    246         id = doregister((__processor_id_t*)&this);
    247 
    248         // Lock the RWlock so no-one pushes/pops while we are changing the queue
    249         uint_fast32_t last_size = ready_mutate_lock();
    250 
    251                 // Adjust the ready queue size
    252                 ready_queue_grow( cltr );
    253 
    254         // Unlock the RWlock
    255         ready_mutate_unlock( last_size );
    256 
    257253        __cfadbg_print_safe(runtime_core, "Kernel : core %p created\n", &this);
    258 }
    259 
    260 // Not a ctor, it just preps the destruction but should not destroy members
    261 void deinit(processor & this) {
    262         // Lock the RWlock so no-one pushes/pops while we are changing the queue
    263         uint_fast32_t last_size = ready_mutate_lock();
    264 
    265                 // Adjust the ready queue size
    266                 ready_queue_shrink( this.cltr );
    267 
    268                 // Make sure we aren't on the idle queue
    269                 unsafe_remove( this.cltr->idles, &this );
    270 
    271         // Unlock the RWlock
    272         ready_mutate_unlock( last_size );
    273 
    274         // Finally we don't need the read_lock any more
    275         unregister((__processor_id_t*)&this);
    276 }
    277 
    278 void ?{}(processor & this, const char name[], cluster & _cltr) {
    279         ( this.idle ){};
    280         ( this.terminated ){ 0 };
    281         ( this.runner ){};
    282         init( this, name, _cltr );
    283 
    284         __cfadbg_print_safe(runtime_core, "Kernel : Starting core %p\n", &this);
    285 
    286         this.stack = __create_pthread( &this.kernel_thread, __invoke_processor, (void *)&this );
    287 
    288254}
    289255
     
    303269
    304270        free( this.stack );
    305 
    306         deinit( this );
    307271
    308272        __atomic_fetch_sub( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
     
    354318
    355319        __cfadbg_print_safe(runtime_core, "Kernel : core %p starting\n", this);
    356         #if !defined(__CFA_NO_STATISTICS__)
    357                 if( this->print_halts ) {
    358                         __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->id, this->name, (void*)this);
    359                 }
    360         #endif
     320
     321        // register the processor unless it's the main thread which is handled in the boot sequence
     322        if(this != mainProcessor) {
     323                this->id = doregister((__processor_id_t*)this);
     324                #if !defined(__CFA_NO_STATISTICS__)
     325                        if( this->print_halts ) {
     326                                __cfaabi_bits_print_safe( STDOUT_FILENO, "Processor : %d - %s (%p)\n", this->id, this->name, (void*)this);
     327                        }
     328                #endif
     329
     330                // Lock the RWlock so no-one pushes/pops while we are changing the queue
     331                uint_fast32_t last_size = ready_mutate_lock();
     332
     333                        // Adjust the ready queue size
     334                        ready_queue_grow( this->cltr );
     335
     336                // Unlock the RWlock
     337                ready_mutate_unlock( last_size );
     338        }
    361339
    362340        {
     
    397375        V( this->terminated );
    398376
    399         if(this == mainProcessor) {
     377        // unregister the processor unless it's the main thread which is handled in the boot sequence
     378        if(this != mainProcessor) {
     379                // Lock the RWlock so no-one pushes/pops while we are changing the queue
     380                uint_fast32_t last_size = ready_mutate_lock();
     381
     382                        // Adjust the ready queue size
     383                        ready_queue_shrink( this->cltr );
     384
     385                        // Make sure we aren't on the idle queue
     386                        #if !defined(__CFA_NO_STATISTICS__)
     387                                bool removed =
     388                        #endif
     389                        unsafe_remove( this->cltr->idles, this );
     390
     391                        #if !defined(__CFA_NO_STATISTICS__)
     392                                if(removed) __tls_stats()->ready.sleep.exits++;
     393                        #endif
     394
     395                // Unlock the RWlock
     396                ready_mutate_unlock( last_size );
     397
     398                // Finally we don't need the read_lock any more
     399                unregister((__processor_id_t*)this);
     400        }
     401        else {
    400402                // HACK : the coroutine context switch expects this_thread to be set
    401403                // and it make sense for it to be set in all other cases except here
     
    857859
    858860        void ?{}(processor & this) with( this ) {
    859                 ( this.idle ){};
    860                 ( this.terminated ){ 0 };
    861                 ( this.runner ){};
    862                 init( this, "Main Processor", *mainCluster );
     861                name = "Main Processor";
     862                cltr = mainCluster;
     863                terminated{ 0 };
     864                do_terminate = false;
     865                preemption_alarm = 0p;
     866                pending_preemption = false;
    863867                kernel_thread = pthread_self();
     868                id = -1u;
     869
     870                #if !defined(__CFA_NO_STATISTICS__)
     871                        print_stats = false;
     872                        print_halts = false;
     873                #endif
    864874
    865875                runner{ &this };
    866876                __cfadbg_print_safe(runtime_core, "Kernel : constructed main processor context %p\n", &runner);
     877
     878                __atomic_fetch_add( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
    867879        }
    868880
     
    871883        mainProcessor = (processor *)&storage_mainProcessor;
    872884        (*mainProcessor){};
     885
     886        mainProcessor->id = doregister( (__processor_id_t*)mainProcessor);
    873887
    874888        //initialize the global state variables
     
    930944        kernel_stop_preemption();
    931945
     946        unregister((__processor_id_t*)mainProcessor);
     947
    932948        // Destroy the main processor and its context in reverse order of construction
    933949        // These were manually constructed so we need manually destroy them
    934950        void ^?{}(processor & this) with( this ){
    935                 deinit( this );
    936 
    937951                /* paranoid */ verify( this.do_terminate == true );
    938952                __atomic_fetch_sub( &cltr->nprocessors, 1u, __ATOMIC_SEQ_CST );
  • libcfa/src/concurrency/ready_queue.cfa

    r04b73b6 rf0c3120  
    186186//=======================================================================
    187187void ?{}(__ready_queue_t & this) with (this) {
    188         lanes.data  = 0p;
    189         lanes.count = 0;
     188
     189        lanes.data = alloc(4);
     190        for( i; 4 ) {
     191                (lanes.data[i]){};
     192        }
     193        lanes.count = 4;
     194        snzi{ log2( lanes.count / 8 ) };
    190195}
    191196
    192197void ^?{}(__ready_queue_t & this) with (this) {
    193         verify( 0  == lanes.count );
     198        verify( 4  == lanes.count );
    194199        verify( !query( snzi ) );
     200
     201        ^(snzi){};
     202
     203        for( i; 4 ) {
     204                ^(lanes.data[i]){};
     205        }
    195206        free(lanes.data);
    196207}
     
    484495}
    485496
    486 #warning remove when alloc is fixed
    487 forall( dtype T | sized(T) )
    488 static inline T * correct_alloc( T ptr[], size_t dim ) {
    489         if( dim == 0 ) {
    490                 free(ptr);
    491                 return 0p;
    492         }
    493         T * temp = alloc( dim );
    494         if(ptr) {
    495                 memcpy( temp, ptr, dim * sizeof(T));
    496                 free(ptr);
    497         }
    498         return temp;
    499 }
    500 
    501497// Grow the ready queue
    502498void ready_queue_grow  (struct cluster * cltr) {
     
    517513
    518514                // Allocate new array (uses realloc and memcpies the data)
    519                 lanes.data = correct_alloc(lanes.data, ncount);
     515                lanes.data = alloc(lanes.data, ncount);
    520516
    521517                // Fix the moved data
     
    562558                size_t ocount = lanes.count;
    563559                // Check that we have some space left
    564                 if(ocount < 4) abort("Program attempted to destroy more Ready Queues than were created");
     560                if(ocount < 8) abort("Program attempted to destroy more Ready Queues than were created");
    565561
    566562                // reduce the actual count so push doesn't use the old queues
     
    604600
    605601                // Allocate new array (uses realloc and memcpies the data)
    606                 lanes.data = correct_alloc(lanes.data, lanes.count);
     602                lanes.data = alloc(lanes.data, lanes.count);
    607603
    608604                // Fix the moved data
  • libcfa/src/concurrency/snzi.hfa

    r04b73b6 rf0c3120  
    120120//--------------------------------------------------
    121121// SNZI object
    122 void  ?{}( __snzi_t & this ) {
    123         this.mask = 0;
    124         this.root = 0;
    125         this.nodes = 0p;
    126 }
    127 
    128122void  ?{}( __snzi_t & this, unsigned depth ) with( this ) {
    129123        mask = (1 << depth) - 1;
  • libcfa/src/concurrency/stats.cfa

    r04b73b6 rf0c3120  
    2424                stats->ready.sleep.exits   = 0;
    2525
    26                 #if defined(CFA_HAVE_LINUX_IO_URING_H)
     26                #if defined(HAVE_LINUX_IO_URING_H)
    2727                        stats->io.submit_q.submit_avg.rdy = 0;
    2828                        stats->io.submit_q.submit_avg.csm = 0;
     
    5959                __atomic_fetch_add( &cltr->ready.sleep.exits  , proc->ready.sleep.exits  , __ATOMIC_SEQ_CST );
    6060
    61                 #if defined(CFA_HAVE_LINUX_IO_URING_H)
     61                #if defined(HAVE_LINUX_IO_URING_H)
    6262                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.rdy          , proc->io.submit_q.submit_avg.rdy          , __ATOMIC_SEQ_CST );
    6363                        __atomic_fetch_add( &cltr->io.submit_q.submit_avg.csm          , proc->io.submit_q.submit_avg.csm          , __ATOMIC_SEQ_CST );
     
    121121                }
    122122
    123                 #if defined(CFA_HAVE_LINUX_IO_URING_H)
     123                #if defined(HAVE_LINUX_IO_URING_H)
    124124                        if( flags & CFA_STATS_IO ) {
    125125                                double avgrdy = ((double)io.submit_q.submit_avg.rdy) / io.submit_q.submit_avg.cnt;
  • libcfa/src/concurrency/stats.hfa

    r04b73b6 rf0c3120  
    1111        enum {
    1212                CFA_STATS_READY_Q  = 0x01,
    13                 #if defined(CFA_HAVE_LINUX_IO_URING_H)
     13                #if defined(HAVE_LINUX_IO_URING_H)
    1414                        CFA_STATS_IO = 0x02,
    1515                #endif
     
    6464        };
    6565
    66         #if defined(CFA_HAVE_LINUX_IO_URING_H)
     66        #if defined(HAVE_LINUX_IO_URING_H)
    6767                struct __attribute__((aligned(64))) __stats_io_t{
    6868                        struct {
     
    9999        struct __attribute__((aligned(128))) __stats_t {
    100100                __stats_readQ_t ready;
    101                 #if defined(CFA_HAVE_LINUX_IO_URING_H)
     101                #if defined(HAVE_LINUX_IO_URING_H)
    102102                        __stats_io_t    io;
    103103                #endif
  • libcfa/src/heap.cfa

    r04b73b6 rf0c3120  
    1010// Created On       : Tue Dec 19 21:58:35 2017
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 20 23:00:32 2020
    13 // Update Count     : 808
     12// Last Modified On : Sat Jun 13 22:42:15 2020
     13// Update Count     : 805
    1414//
    1515
     
    901901          if ( oalign == 0 && size <= odsize && odsize <= size * 2 ) { // allow 50% wasted storage for smaller size
    902902                        header->kind.real.blockSize &= -2;                      // no alignment and turn off 0 fill
    903                         if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    904903                        return oaddr;
    905904                } // if
     
    930929
    931930                size_t odsize = dataStorage( bsize, oaddr, header ); // data storage available in bucket
    932           if ( size <= odsize && odsize <= size * 2 ) {         // allow up to 50% wasted storage in smaller size
    933                         if ( size != odsize ) header->kind.real.size = size; // reset allocation size
     931          if ( size <= odsize && odsize <= size * 2 ) { // allow up to 50% wasted storage in smaller size
     932                        // Do not know size of original allocation => cannot do 0 fill for any additional space because do not know
     933                        // where to start filling, i.e., do not overwrite existing values in space.
    934934                        return oaddr;
    935935                } // if
     
    10981098        // Returns original total allocation size (not bucket size) => array size is dimension * sizeif(T).
    10991099        size_t malloc_size( void * addr ) {
    1100           if ( unlikely( addr == 0p ) ) return 0;                       // null allocation has zero size
     1100          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
    11011101                HeapManager.Storage.Header * header = headerAddr( addr );
    11021102                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     
    11081108        // Set allocation size and return previous size.
    11091109        size_t $malloc_size_set( void * addr, size_t size ) {
    1110           if ( unlikely( addr == 0p ) ) return 0;                       // null allocation has 0 size
     1110          if ( unlikely( addr == 0p ) ) return false;           // null allocation is not zero fill
    11111111                HeapManager.Storage.Header * header = headerAddr( addr );
    11121112                if ( (header->kind.fake.alignment & 1) == 1 ) { // fake header ?
     
    12271227                if ( size <= odsize && odsize <= size * 2 ) {   // allow 50% wasted storage for smaller size
    12281228                        header->kind.real.blockSize &= -2;                      // turn off 0 fill
    1229                         if ( size != odsize ) header->kind.real.size = size; // reset allocation size
    12301229                        return oaddr;
    12311230                } // if
  • libcfa/src/heap.hfa

    r04b73b6 rf0c3120  
    1010// Created On       : Tue May 26 11:23:55 2020
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 20 18:52:31 2020
    13 // Update Count     : 11
     12// Last Modified On : Mon Jun  1 21:19:00 2020
     13// Update Count     : 10
    1414//
    1515
     
    3535        void * resize( void * oaddr, size_t size );
    3636        void * amemalign( size_t align, size_t dim, size_t elemSize );
    37         void * cmemalign( size_t align, size_t dim, size_t elemSize );
     37        void * cmemalign( size_t align, size_t noOfElems, size_t elemSize );
    3838        size_t malloc_alignment( void * addr );
    3939        bool malloc_zero_fill( void * addr );
  • libcfa/src/iostream.cfa

    r04b73b6 rf0c3120  
    1010// Created On       : Wed May 27 17:56:53 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 20 15:00:37 2020
    13 // Update Count     : 1124
     12// Last Modified On : Thu Jul 16 07:43:31 2020
     13// Update Count     : 1102
    1414//
    1515
     
    167167        #define P10_UINT64 10_000_000_000_000_000_000_ULL       // 19 zeroes
    168168
    169         static inline void base10_128( ostype & os, unsigned int128 val ) {
    170 #if defined(__GNUC__) && __GNUC_PREREQ(7,0)                             // gcc version >= 7
     169        static void base10_128( ostype & os, unsigned int128 val ) {
    171170                if ( val > P10_UINT64 ) {
    172 #else
    173                 if ( (uint64_t)(val >> 64) != 0 || (uint64_t)val > P10_UINT64 ) { // patch gcc 5 & 6 -O3 bug
    174 #endif // __GNUC_PREREQ(7,0)
    175171                        base10_128( os, val / P10_UINT64 );                     // recursive
    176172                        fmt( os, "%.19lu", (uint64_t)(val % P10_UINT64) );
     
    180176        } // base10_128
    181177
    182         static inline void base10_128( ostype & os, int128 val ) {
     178        static void base10_128( ostype & os, int128 val ) {
    183179                if ( val < 0 ) {
    184180                        fmt( os, "-" );                                                         // leading negative sign
  • libcfa/src/stdlib.cfa

    r04b73b6 rf0c3120  
    99// Author           : Peter A. Buhr
    1010// Created On       : Thu Jan 28 17:10:29 2016
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sun Jul 19 15:05:28 2020
    13 // Update Count     : 501
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jun  2 16:46:00 2020
     13// Update Count     : 500
    1414//
    1515
     
    2525
    2626//---------------------------------------
     27
     28forall( dtype T | sized(T) ) {
     29        T * alloc_set( T ptr[], size_t dim, char fill ) {       // realloc array with fill
     30                size_t olen = malloc_usable_size( ptr );                // current allocation
     31                void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     32                size_t nlen = malloc_usable_size( nptr );               // new allocation
     33                if ( nlen > olen ) {                                                    // larger ?
     34                        memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
     35                } // if
     36                return (T *)nptr;
     37        } // alloc_set
     38
     39        T * alloc_set( T ptr[], size_t dim, T fill ) {          // realloc array with fill
     40                size_t olen = malloc_usable_size( ptr );                // current allocation
     41                void * nptr = (void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
     42                size_t nlen = malloc_usable_size( nptr );               // new allocation
     43                if ( nlen > olen ) {                                                    // larger ?
     44                        for ( i; malloc_size( ptr ) / sizeof(T) ~ dim ) {
     45                                memcpy( &ptr[i], &fill, sizeof(T) );    // initialize with fill value
     46                        } // for
     47                } // if
     48                return (T *)nptr;
     49        } // alloc_align_set
     50
     51        T * alloc_align_set( T ptr[], size_t align, char fill ) { // aligned realloc with fill
     52                size_t olen = malloc_usable_size( ptr );                // current allocation
     53                void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     54                // char * nptr = alloc_align( ptr, align );
     55                size_t nlen = malloc_usable_size( nptr );               // new allocation
     56                if ( nlen > olen ) {                                                    // larger ?
     57                        memset( (char *)nptr + olen, (int)fill, nlen - olen ); // initialize added storage
     58                } // if
     59                return (T *)nptr;
     60        } // alloc_align_set
     61
     62        T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ) { // aligned realloc with fill
     63                size_t olen = malloc_usable_size( ptr );                // current allocation
     64                void * nptr = (void *)realloc( (void *)ptr, align, sizeof(T) ); // CFA realloc
     65                // char * nptr = alloc_align( ptr, align );
     66                size_t nlen = malloc_usable_size( nptr );               // new allocation
     67                if ( nlen > olen ) {                                                    // larger ?
     68                        for ( i; dim ) { memcpy( &ptr[i], &fill, sizeof(T) ); } // initialize with fill value
     69                } // if
     70                return (T *)nptr;
     71        } // alloc_align_set
     72} // distribution
    2773
    2874// allocation/deallocation and constructor/destructor, non-array types
  • libcfa/src/stdlib.hfa

    r04b73b6 rf0c3120  
    99// Author           : Peter A. Buhr
    1010// Created On       : Thu Jan 28 17:12:35 2016
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Jul 21 07:58:05 2020
    13 // Update Count     : 475
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tue Jun  2 16:47:00 2020
     13// Update Count     : 451
    1414//
    1515
     
    3939//---------------------------------------
    4040
    41 // Macro because of returns
    42 #define $VAR_ALLOC( allocation, alignment ) \
    43         if ( _Alignof(T) <= libAlign() ) return (T *)(void *)allocation( (size_t)sizeof(T) ); /* C allocation */ \
    44         else return (T *)alignment( _Alignof(T), sizeof(T) )
    45 
    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 
    50 #define $RE_SPECIALS( ptr, size, allocation, alignment ) \
    51         if ( unlikely( size == 0 ) || unlikely( ptr == 0p ) ) { \
    52                 if ( unlikely( size == 0 ) ) free( ptr ); \
    53                 $VAR_ALLOC( malloc, memalign ); \
    54         } /* if */
    55 
    5641static inline forall( dtype T | sized(T) ) {
    5742        // Cforall safe equivalents, i.e., implicit size specification
    5843
    5944        T * malloc( void ) {
    60                 $VAR_ALLOC( malloc, memalign );
     45                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)malloc( (size_t)sizeof(T) ); // C malloc
     46                else return (T *)memalign( _Alignof(T), sizeof(T) );
    6147        } // malloc
    6248
    6349        T * aalloc( size_t dim ) {
    64                 $ARRAY_ALLOC( aalloc, amemalign, dim );
     50                if ( _Alignof(T) <= libAlign() ) return (T *)(void *)aalloc( dim, (size_t)sizeof(T) ); // CFA aalloc
     51                else return (T *)amemalign( _Alignof(T), dim, sizeof(T) );
    6552        } // aalloc
    6653
    6754        T * calloc( size_t dim ) {
    68                 $ARRAY_ALLOC( calloc, cmemalign, dim );
     55                if ( _Alignof(T) <= libAlign() )return (T *)(void *)calloc( dim, sizeof(T) ); // C calloc
     56                else return (T *)cmemalign( _Alignof(T), dim, sizeof(T) );
    6957        } // calloc
    7058
    71         T * resize( T * ptr, size_t size ) {                            // CFA resize, eliminate return-type cast
    72                 $RE_SPECIALS( ptr, size, malloc, memalign );
    73                 return (T *)(void *)resize( (void *)ptr, size ); // CFA resize
     59        T * resize( T * ptr, size_t size ) {                            // CFA realloc, eliminate return-type cast
     60                return (T *)(void *)resize( (void *)ptr, size ); // C realloc
    7461        } // resize
    7562
    7663        T * realloc( T * ptr, size_t size ) {                           // CFA realloc, eliminate return-type cast
    77                 $RE_SPECIALS( ptr, size, malloc, memalign );
    7864                return (T *)(void *)realloc( (void *)ptr, size ); // C realloc
    7965        } // realloc
     
    132118
    133119        T * alloc( T ptr[], size_t dim, bool copy = true ) {
    134                 if ( copy ) {
    135                         return realloc( ptr, dim * sizeof(T) );         // CFA realloc
     120                if ( copy ) {                                                                   // realloc
     121                        return (T *)(void *)realloc( (void *)ptr, dim * sizeof(T) ); // C realloc
    136122                } else {
    137                         return resize( ptr, dim * sizeof(T) );          // CFA resize
     123                        return resize( ptr, dim * sizeof(T) );          // resize
    138124                } // if
    139125        } // alloc
     
    160146                return (T *)memcpy( (T *)alloc( dim ), fill, dim * sizeof(T) ); // initialize with fill value
    161147        } // alloc
    162 
    163         T * alloc_set( T ptr[], size_t dim, char fill ) {       // realloc array with fill
    164                 size_t osize = malloc_size( ptr );                              // current allocation
    165                 size_t nsize = dim * sizeof(T);                                 // new allocation
    166                 T * nptr = realloc( ptr, nsize );                               // CFA realloc
    167                 if ( nsize > osize ) {                                                  // larger ?
    168                         memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage
    169                 } // if
    170                 return (T *)nptr;
    171         } // alloc_set
    172 
    173         T * alloc_set( T ptr[], size_t dim, T & fill ) {        // realloc array with fill
    174                 size_t odim = malloc_size( ptr ) / sizeof(T);   // current dimension
    175                 size_t nsize = dim * sizeof(T);                                 // new allocation
    176                 size_t ndim = nsize / sizeof(T);                                // new dimension
    177                 T * nptr = realloc( ptr, nsize );                               // CFA realloc
    178                 if ( ndim > odim ) {                                                    // larger ?
    179                         for ( i; odim ~ ndim ) {
    180                                 memcpy( &nptr[i], &fill, sizeof(T) );   // initialize with fill value
    181                         } // for
    182                 } // if
    183                 return (T *)nptr;
    184         } // alloc_align_set
     148} // distribution
     149
     150forall( dtype T | sized(T) ) {
     151        T * alloc_set( T ptr[], size_t dim, char fill );        // realloc array with fill
     152        T * alloc_set( T ptr[], size_t dim, T fill );           // realloc array with fill
    185153} // distribution
    186154
     
    228196                return (T *)memcpy( (T *)alloc_align( align, dim ), fill, dim * sizeof(T) );
    229197        } // alloc_align
    230 
    231         T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ) {
    232                 size_t osize = malloc_size( ptr );                              // current allocation
    233                 size_t nsize = dim * sizeof(T);                                 // new allocation
    234                 T * nptr = realloc( ptr, align, nsize );                // CFA realloc
    235                 if ( nsize > osize ) {                                                  // larger ?
    236                         memset( (char *)nptr + osize, (int)fill, nsize - osize ); // initialize added storage
    237                 } // if
    238                 return (T *)nptr;
    239         } // alloc_align_set
    240 
    241         T * alloc_align_set( T ptr[], size_t align, size_t dim, T & fill ) {
    242                 size_t odim = malloc_size( ptr ) / sizeof(T);   // current dimension
    243                 size_t nsize = dim * sizeof(T);                                 // new allocation
    244                 size_t ndim = nsize / sizeof(T);                                // new dimension
    245                 T * nptr = realloc( ptr, align, nsize );                // CFA realloc
    246                 if ( ndim > odim ) {                                                    // larger ?
    247                         for ( i; odim ~ ndim ) {
    248                                 memcpy( &nptr[i], &fill, sizeof(T) );   // initialize with fill value
    249                         } // for
    250                 } // if
    251                 return (T *)nptr;
    252         } // alloc_align_set
     198} // distribution
     199
     200forall( dtype T | sized(T) ) {
     201        T * alloc_align_set( T ptr[], size_t align, char fill ); // aligned realloc with fill
     202        T * alloc_align_set( T ptr[], size_t align, T fill ); // aligned realloc with fill
     203        T * alloc_align_set( T ptr[], size_t align, size_t dim, char fill ); // aligned realloc array with fill
     204        T * alloc_align_set( T ptr[], size_t align, size_t dim, T fill ); // aligned realloc array with fill
    253205} // distribution
    254206
  • src/Common/PassVisitor.proto.h

    r04b73b6 rf0c3120  
    3838        };
    3939
    40         std::stack< cleanup_t, std::vector< cleanup_t > > cleanups;
     40        std::stack< cleanup_t > cleanups;
    4141};
    4242
  • src/Virtual/ExpandCasts.cc

    r04b73b6 rf0c3120  
    1010// Created On       : Mon Jul 24 13:59:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Jul 22 10:04:00 2020
    13 // Update Count     : 3
     12// Last Modified On : Tue May 26 14:37:00 2020
     13// Update Count     : 2
    1414//
    1515
     
    2424#include "Common/PassVisitor.h"    // for PassVisitor
    2525#include "Common/SemanticError.h"  // for SemanticError
    26 #include "SymTab/Mangler.h"        // for mangleType
    2726#include "SynTree/Declaration.h"   // for ObjectDecl, StructDecl, FunctionDecl
    2827#include "SynTree/Expression.h"    // for VirtualCastExpr, CastExpr, Address...
     
    3332namespace Virtual {
    3433
    35         // Indented until the new ast code gets added.
    36 
    37         /// Maps virtual table types the instance for that type.
    38         class VirtualTableMap final {
    39                 std::unordered_map<std::string, ObjectDecl *> vtable_instances;
    40         public:
    41                 ObjectDecl * insert( ObjectDecl * vtableDecl ) {
    42                         std::string const & mangledName = SymTab::Mangler::mangleType( vtableDecl->type );
    43                         ObjectDecl *& value = vtable_instances[ mangledName ];
    44                         if ( value ) {
    45                                 if ( vtableDecl->storageClasses.is_extern ) {
    46                                         return nullptr;
    47                                 } else if ( ! value->storageClasses.is_extern ) {
    48                                         return value;
    49                                 }
    50                         }
    51                         value = vtableDecl;
    52                         return nullptr;
    53                 }
    54 
    55                 ObjectDecl * lookup( const Type * vtableType ) {
    56                         std::string const & mangledName = SymTab::Mangler::mangleType( vtableType );
    57                         const auto it = vtable_instances.find( mangledName );
    58                         return ( vtable_instances.end() == it ) ? nullptr : it->second;
    59                 }
    60         };
    61 
    6234        /* Currently virtual depends on the rather brittle name matching between
    6335         * a (strict/explicate) virtual type, its vtable type and the vtable
     
    6638         * and use that information to create better error messages.
    6739         */
    68 
    69         namespace {
    7040
    7141        std::string get_vtable_name( std::string const & name ) {
     
    8555        }
    8656
     57        bool is_vtable_name( std::string const & name ) {
     58                return (name.substr( name.size() - 7 ) == "_vtable" );
     59        }
     60
    8761        bool is_vtable_inst_name( std::string const & name ) {
    8862                return 17 < name.size() &&
     
    9064        }
    9165
    92         } // namespace
    93 
    9466        class VirtualCastCore {
    95                 VirtualTableMap vtable_instances;
    96                 FunctionDecl *vcast_decl;
    97                 StructDecl *pvt_decl;
     67        std::map<std::string, ObjectDecl *> vtable_instances;
     68        FunctionDecl *vcast_decl;
     69        StructDecl *pvt_decl;
    9870
    9971                Type * pointer_to_pvt(int level_of_indirection) {
     
    135107        void VirtualCastCore::premutate( ObjectDecl * objectDecl ) {
    136108                if ( is_vtable_inst_name( objectDecl->get_name() ) ) {
    137                         if ( ObjectDecl * existing = vtable_instances.insert( objectDecl ) ) {
    138                                 std::string msg = "Repeated instance of virtual table, original found at: ";
    139                                 msg += existing->location.filename;
    140                                 msg += ":" + toString( existing->location.first_line );
    141                                 SemanticError( objectDecl->location, msg );
    142                         }
     109                        vtable_instances[objectDecl->get_name()] = objectDecl;
    143110                }
    144111        }
    145112
    146         namespace {
    147 
    148         /// Better error locations for generated casts.
    149         CodeLocation castLocation( const VirtualCastExpr * castExpr ) {
     113        // Better error locations for generated casts.
     114        static CodeLocation castLocation( VirtualCastExpr * castExpr ) {
    150115                if ( castExpr->location.isSet() ) {
    151116                        return castExpr->location;
     
    159124        }
    160125
    161         [[noreturn]] void castError( const VirtualCastExpr * castExpr, std::string const & message ) {
    162                 SemanticError( castLocation( castExpr ), message );
    163         }
    164 
    165         /// Get the virtual table type used in a virtual cast.
    166         Type * getVirtualTableType( const VirtualCastExpr * castExpr ) {
    167                 const Type * objectType;
    168                 if ( auto target = dynamic_cast<const PointerType *>( castExpr->result ) ) {
    169                         objectType = target->base;
    170                 } else if ( auto target = dynamic_cast<const ReferenceType *>( castExpr->result ) ) {
    171                         objectType = target->base;
    172                 } else {
    173                         castError( castExpr, "Virtual cast type must be a pointer or reference type." );
    174                 }
    175                 assert( objectType );
    176 
    177                 const StructInstType * structType = dynamic_cast<const StructInstType *>( objectType );
    178                 if ( nullptr == structType ) {
    179                         castError( castExpr, "Virtual cast type must refer to a structure type." );
    180                 }
    181                 const StructDecl * structDecl = structType->baseStruct;
    182                 assert( structDecl );
    183 
    184                 const ObjectDecl * fieldDecl = nullptr;
    185                 if ( 0 < structDecl->members.size() ) {
    186                         const Declaration * memberDecl = structDecl->members.front();
    187                         assert( memberDecl );
    188                         fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl );
    189                         if ( fieldDecl && fieldDecl->name != "virtual_table" ) {
    190                                 fieldDecl = nullptr;
    191                         }
    192                 }
    193                 if ( nullptr == fieldDecl ) {
    194                         castError( castExpr, "Virtual cast type must have a leading virtual_table field." );
    195                 }
    196                 const PointerType * fieldType = dynamic_cast<const PointerType *>( fieldDecl->type );
    197                 if ( nullptr == fieldType ) {
    198                         castError( castExpr, "Virtual cast type virtual_table field is not a pointer." );
    199                 }
    200                 assert( fieldType->base );
    201                 auto virtualStructType = dynamic_cast<const StructInstType *>( fieldType->base );
    202                 assert( virtualStructType );
    203 
    204                 // Here is the type, but if it is polymorphic it will have lost information.
    205                 // (Always a clone so that it may always be deleted.)
    206                 StructInstType * virtualType = virtualStructType->clone();
    207                 if ( ! structType->parameters.empty() ) {
    208                         deleteAll( virtualType->parameters );
    209                         virtualType->parameters.clear();
    210                         cloneAll( structType->parameters, virtualType->parameters );
    211                 }
    212                 return virtualType;
    213         }
    214 
    215         } // namespace
    216 
    217126        Expression * VirtualCastCore::postmutate( VirtualCastExpr * castExpr ) {
    218                 assertf( castExpr->result, "Virtual Cast target not found before expansion." );
     127                assertf( castExpr->get_result(), "Virtual Cast target not found before expansion." );
    219128
    220129                assert( vcast_decl );
    221130                assert( pvt_decl );
    222131
    223                 const Type * vtable_type = getVirtualTableType( castExpr );
    224                 ObjectDecl * table = vtable_instances.lookup( vtable_type );
    225                 if ( nullptr == table ) {
     132                // Get the base type of the pointer/reference.
     133                Type * base;
     134                Type * result_type = castExpr->result;
     135                if ( PointerType * target = dynamic_cast<PointerType *>( result_type ) ) {
     136                        base = target->base;
     137                } else if ( ReferenceType * target = dynamic_cast<ReferenceType *>( result_type ) ) {
     138                        base = target->base;
     139                } else {
    226140                        SemanticError( castLocation( castExpr ),
    227                                 "Could not find virtual table instance." );
     141                                "Virtual cast type must be a pointer or reference type." );
    228142                }
     143
     144                StructInstType * target_struct = dynamic_cast<StructInstType *>( base );
     145                if ( nullptr == target_struct ) {
     146                        SemanticError( castLocation( castExpr ),
     147                                "Virtual cast type must refer to a structure type." );
     148                }
     149                StructDecl * target_decl = target_struct->get_baseStruct();
     150
     151                std::map<std::string, ObjectDecl *>::iterator found =
     152                        vtable_instances.find( get_vtable_inst_name( target_decl->get_name() ) );
     153                if ( vtable_instances.end() == found ) {
     154                        SemanticError( castLocation( castExpr ),
     155                                "Virtual cast type does not have a virtual table instance." );
     156                }
     157                ObjectDecl * table = found->second;
    229158
    230159                Expression * result = new CastExpr(
     
    245174                castExpr->set_result( nullptr );
    246175                delete castExpr;
    247                 delete vtable_type;
    248176                return result;
    249177        }
  • tests/.expect/alloc.txt

    r04b73b6 rf0c3120  
    30300xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    3131CFA realloc array alloc, fill
    32 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     320xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
    3333CFA realloc array alloc, fill
    34340xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef
    3535CFA realloc array alloc, fill
    36 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
     360xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0xdeadbeef 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0x1010101 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede 0xdededede
    3737
    3838C   memalign 42 42.5
Note: See TracChangeset for help on using the changeset viewer.