Changeset 04b73b6 for benchmark


Ignore:
Timestamp:
Jul 23, 2020, 3:37:05 PM (6 years ago)
Author:
Thierry Delisle <tdelisle@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
f4ec4a90
Parents:
f0c3120 (diff), e262b5e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
benchmark/io/http
Files:
1 added
9 edited

Legend:

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

    rf0c3120 r04b73b6  
    5656}
    5757
     58static 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}
    5871
    5972struct {
     
    6982
    7083[int fd, size_t size] get_file( * const char file, size_t len ) {
    71         uint32_t idx = murmur3_32( (const uint8_t *)file, len, options.hash_seed ) % file_cache.size;
     84        uint32_t idx = murmur3_32( (const uint8_t *)file, len, options.file_cache.hash_seed ) % file_cache.size;
    7285
    7386        for(int i = 0;; i++) {
     
    8699
    87100int put_file( cache_line & entry ) {
    88         uint32_t idx = murmur3_32( (const uint8_t *)entry.file, strlen(entry.file), options.hash_seed ) % file_cache.size;
     101        uint32_t idx = murmur3_32( (const uint8_t *)entry.file, strlen(entry.file), options.file_cache.hash_seed ) % file_cache.size;
    89102
    90103        int i = 0;
     
    101114void fill_cache( const char * path ) {
    102115        int ret;
     116        ret = chdir(path);
     117        if(ret < 0) {
     118                abort( "chdir error: (%d) %s\n", (int)errno, strerror(errno) );
     119        }
     120
    103121        size_t fcount = 0;
    104122        size_t fsize = 16;
     
    118136                raw[idx].file = strdup(fpath+2);
    119137                raw[idx].size = sb->st_size;
    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) );
     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                        }
    123143                }
    124144                return 0;
    125145        }
    126146
    127         ret = ftw(path, walk, 10);
     147        ret = ftw(".", walk, 10);
    128148        if(ret < 0) {
    129149                abort( "ftw error: (%d) %s\n", (int)errno, strerror(errno) );
     
    135155
    136156        // Step 2 create the cache
    137         file_cache.size = options.file_cache_size > 0 ? options.file_cache_size : fsize;
     157        file_cache.size = options.file_cache.size > 0 ? options.file_cache.size : fsize;
    138158        if( file_cache.size < fcount ) {
    139159                abort("File Cache too small\n");
    140160        }
    141161
    142         file_cache.entries = anew(fsize);
     162        file_cache.entries = anew(file_cache.size);
    143163
    144164        // Step 3 fill the cache
    145165        int conflicts = 0;
    146166        for(i; fcount) {
    147                 printf("Added file %s\n", raw[i].file);
    148167                conflicts += put_file( raw[i] );
    149168        }
    150169        printf("Filled cache from path \"%s\" with %zu files\n", path, fcount);
    151170        if( conflicts > 0 ) {
    152                 printf("Found %d conflicts (seed: %u)\n", conflicts, options.hash_seed);
     171                printf("Found %d conflicts (seed: %u)\n", conflicts, options.file_cache.hash_seed);
    153172                #if defined(REJECT_CONFLICTS)
    154173                        abort("Conflicts found in the cache");
     
    156175        }
    157176
     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
    158190        // Step 4 clean up
    159191        free( raw );
    160192}
     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
    161202
    162203void close_cache() {
  • benchmark/io/http/filecache.hfa

    rf0c3120 r04b73b6  
    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 );
    1314void close_cache();
  • benchmark/io/http/main.cfa

    rf0c3120 r04b73b6  
    1717#include "filecache.hfa"
    1818#include "options.hfa"
    19 #include "parseargs.hfa"
    2019#include "worker.hfa"
    2120
     
    2322// Globals
    2423//=============================================================================================
    25 Options options @= {
    26         0,
    27         42u,
    28         0,
    29         false,
    30         false,
    31         0
    32 };
    33 
    3424channel & wait_connect;
    3525
     
    3929
    4030void ?{}( ServerProc & this ) {
    41         /* paranoid */ assert( options.the_cluster != 0p );
    42         (this.self){ "Benchmark Processor", *options.the_cluster };
     31        /* paranoid */ assert( options.clopts.instance != 0p );
     32        (this.self){ "Benchmark Processor", *options.clopts.instance };
    4333
    4434        #if !defined(__CFA_NO_STATISTICS__)
    45                 if( options.procstats ) {
    46                         print_stats_at_exit( this.self, options.the_cluster->print_stats );
     35                if( options.clopts.procstats ) {
     36                        print_stats_at_exit( this.self, options.clopts.instance->print_stats );
    4737                }
    48                 if( options.viewhalts ) {
     38                if( options.clopts.viewhalts ) {
    4939                        print_halts( this.self );
    5040                }
     
    5646//============================================================================================='
    5747int 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 = ".";
    6548        //===================
    6649        // Parse args
    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 
     50        const char * path = parse_options(argc, argv);
    7951
    8052        //===================
     
    8557        //===================
    8658        // Open Socket
    87         printf("Listening on port %d\n", port);
     59        printf("Listening on port %d\n", options.socket.port);
    8860        int server_fd = socket(AF_INET, SOCK_STREAM, 0);
    8961        if(server_fd < 0) {
     
    9769        address.sin_family = AF_INET;
    9870        address.sin_addr.s_addr = htonl(INADDR_ANY);
    99         address.sin_port = htons( port );
     71        address.sin_port = htons( options.socket.port );
    10072
    10173        ret = bind( server_fd, (struct sockaddr *)&address, sizeof(address) );
     
    10476        }
    10577
    106         ret = listen( server_fd, backlog );
     78        ret = listen( server_fd, options.socket.backlog );
    10779        if(ret < 0) {
    10880                abort( "listen error: (%d) %s\n", (int)errno, strerror(errno) );
     
    11284        // Run Server Cluster
    11385        {
    114                 cluster cl = { "Server Cluster", cl_flags };
     86                cluster cl = { "Server Cluster", options.clopts.flags };
    11587                #if !defined(__CFA_NO_STATISTICS__)
    11688                        print_stats_at_exit( cl, CFA_STATS_READY_Q | CFA_STATS_IO );
    11789                #endif
    118                 options.the_cluster = &cl;
     90                options.clopts.instance = &cl;
    11991
    120                 channel chan = { chan_size };
     92                channel chan = { options.clopts.chan_size };
    12193                &wait_connect = &chan;
    12294
     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
    123104                {
    124                         ServerProc procs[nprocs];
     105                        ServerProc procs[options.clopts.nprocs];
    125106                        {
    126                                 Worker workers[nworkers];
    127                                 printf("%d workers started on %d processors\n", nworkers, nprocs);
     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);
    128120                                {
    129121                                        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");
    130129                                }
    131                                 printf("Shutting Down\n");
     130                                printf("Acceptor Closed\n");
    132131
    133132                                // Clean-up the workers
    134                                 for(nworkers) {
     133                                for(options.clopts.nworkers) {
    135134                                        put( wait_connect, -1 );
    136135                                }
    137136                        }
     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);
    139147        }
    140148
  • benchmark/io/http/options.hfa

    rf0c3120 r04b73b6  
    66
    77struct Options {
    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;
     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;
    1431};
    1532
    1633extern Options options;
     34
     35const char * parse_options( int argc, char * argv[] );
  • benchmark/io/http/parseargs.cfa

    rf0c3120 r04b73b6  
    33// #include <stdio.h>
    44// #include <stdlib.h>
     5#include <errno.h>
    56#include <string.h>
     7#include <unistd.h>
    68extern "C" {
    79        #include <getopt.h>
     10        #include <sys/ioctl.h>
    811
    912        struct FILE;
     
    1114        extern FILE * stdout;
    1215
     16        extern int fileno(FILE *stream);
     17
    1318        extern int fprintf ( FILE * stream, const char * format, ... );
    14         extern long long int strtoll (const char* str, char** endptr, int base);
     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
     27void 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        }
    1537}
    1638
     
    2547        struct option optarr[opt_count + 2];
    2648        int width = 0;
     49        int max_width = 1_000_000;
    2750        {
    2851                int idx = 0;
     
    93116        }
    94117
    95         USAGE:
    96         fprintf(out, "%s\n", usage);
     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);
    97128
    98129        for(i; opt_count) {
    99                 fprintf(out, "  -%c, --%-*s   %s\n", options[i].short_name, width, options[i].long_name, options[i].help);
     130                printopt(out, width, max_width, options[i].short_name, options[i].long_name, options[i].help);
    100131        }
    101132        fprintf(out, "  -%c, --%-*s   %s\n", 'h', width, "help", "print this help message");
     
    132163}
    133164
     165bool 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
     175bool 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
    134185bool parse(const char * arg, int & value) {
    135186        char * end;
  • benchmark/io/http/parseargs.hfa

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

    rf0c3120 r04b73b6  
    2525};
    2626
    27 _Static_assert( KNOWN_CODES == (sizeof(http_msgs) / sizeof(http_msgs[0])));
     27_Static_assert( KNOWN_CODES == (sizeof(http_msgs ) / sizeof(http_msgs [0])));
     28
     29const 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
     39int code_val(HttpCode code) {
     40        return http_codes[code];
     41}
    2842
    2943static inline int answer( int fd, const char * it, int len) {
     
    6175        for() {
    6276                int ret = cfa_read(fd, it, count);
     77                if(ret == 0 ) return [OK200, true, 0p, 0];
    6378                if(ret < 0 ) {
    64                         if( errno ) return [OK200, true, 0p, 0];
    6579                        if( errno == EAGAIN || errno == EWOULDBLOCK) continue READ;
    6680                        abort( "read error: (%d) %s\n", (int)errno, strerror(errno) );
  • benchmark/io/http/protocol.hfa

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

    rf0c3120 r04b73b6  
    1212#include "filecache.hfa"
    1313
    14 extern "C" {
    15 // extern ssize_t sendfile(int out_fd, int in_fd, off_t *offset, size_t count);
    16 extern 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 
    19 ssize_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 
    2414//=============================================================================================
    2515// Worker Thread
    2616//=============================================================================================
    2717void ?{}( Worker & this ) {
    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) ); }
     18        ((thread&)this){ "Server Worker Thread", *options.clopts.instance };
     19        this.pipe[0] = -1;
     20        this.pipe[1] = -1;
    3121}
    3222
    3323void main( Worker & this ) {
     24        park( __cfaabi_dbg_ctx );
     25        /* paranoid */ assert( this.pipe[0] != -1 );
     26        /* paranoid */ assert( this.pipe[1] != -1 );
     27
    3428        CONNECTION:
    35         while( int fd = take(wait_connect); fd >= 0) {
    36             printf("New connection, waiting for requests\n");
     29        for() {
     30                int fd = take(wait_connect);
     31                if (fd < 0) break;
     32
     33                printf("New connection %d, waiting for requests\n", fd);
    3734                REQUEST:
    3835                for() {
     
    4340
    4441                        // Read the http request
    45                         size_t len = 1024;
     42                        size_t len = options.socket.buflen;
    4643                        char buffer[len];
    4744                        printf("Reading request\n");
     
    5653                        // If this wasn't a request retrun 400
    5754                        if( code != OK200 ) {
    58                                 printf("Invalid Request\n");
     55                                printf("Invalid Request : %d\n", code_val(code));
    5956                                answer_error(fd, code);
    6057                                continue REQUEST;
    6158                        }
    6259
    63                         printf("Request for file %.*s\n", name_size, file);
     60                        printf("Request for file %.*s\n", (int)name_size, file);
    6461
    6562                        // Get the fd from the file cache
     
    9087//=============================================================================================
    9188void ?{}( Acceptor & this, int sockfd, struct sockaddr * addr, socklen_t * addrlen, int flags ) {
    92         ((thread&)this){ "Acceptor Thread", *options.the_cluster };
     89        ((thread&)this){ "Acceptor Thread", *options.clopts.instance };
    9390        this.sockfd  = sockfd;
    9491        this.addr    = addr;
     
    105102                }
    106103
    107             printf("New connection accepted\n");
     104                printf("New connection accepted\n");
    108105                put( wait_connect, ret );
    109       }
     106        }
    110107}
Note: See TracChangeset for help on using the changeset viewer.