int main(int argc, char **argv) { /* parse args */ int c; char *endptr = 0; struct vtab *vt = &vtab_ach; while( (c = getopt( argc, argv, "f:s:p:r:l:gPhH?Vk")) != -1 ) { switch(c) { case 'f': FREQUENCY = strtod(optarg, &endptr); assert(endptr); break; case 's': SECS = strtod(optarg, &endptr); assert(endptr); break; case 'p': SEND_RT = (size_t)atoi(optarg); assert(SEND_RT); break; case 'k': KERNDEV = 1; break; case 'r': RECV_RT = (size_t)atoi(optarg); break; case 'l': RECV_NRT = (size_t)atoi(optarg); break; case 'g': PASS_NO_RT = 1; break; case 'P': vt = &vtab_pipe; break; case 'V': /* version */ ach_print_version("achbench"); exit(EXIT_SUCCESS); case 'h': case 'H': case '?': default: puts("Usage: achbench [OPTION....]\n" "Benchmark Ach IPC\n" "\n" "Note: Disable CPU power-saving to minimize latency\n" "\n" "Options:\n" " -f FREQUENCY, Frequency in Hertz (1000)\n" " -s SECONDS, Duration in seconds (1)\n" " -p COUNT, Real-Time Publishers (1)\n" " -r COUNT, Real-Time Receivers (1)\n" " -l COUNT, Non-Real-Time Receivers (0)\n" " -g, Proceed even if real-time setup fails\n" " -P, Benchmark pipes instead of ach\n" " -k, Use kernel channels\n" ); exit(EXIT_SUCCESS); } } fprintf(stderr, "-f %.2f ", FREQUENCY); fprintf(stderr, "-s %.2f ", SECS); fprintf(stderr, "-r %"PRIuPTR" ", RECV_RT); fprintf(stderr, "-l %"PRIuPTR" ", RECV_NRT); fprintf(stderr, "-p %"PRIuPTR"\n", SEND_RT); size_t i; init_time_chan(); /* setup comms */ vt->setup(); /* fork printer */ pid_t pid_print = fork(); assert( pid_print >= 0 ); if(0 == pid_print ) { print_times(); exit(0); } /* warm up */ for( i = 0; i < 10; i++) get_ticks(); /* compute overhead */ calibrate(); fprintf(stderr,"overhead 0: %fus\n", overhead*1e6); /* fork receivers */ pid_t pid_recv_rt[RECV_RT+RECV_NRT]; /* non-realtime receivers */ for( i = 0; i < RECV_NRT; i ++ ) { pid_recv_rt[i] = fork(); assert( pid_recv_rt[i] >= 0 ); if(0 == pid_recv_rt[i]) { vt->receiver(0); exit(0); } } /* realtime receivers */ for( i = RECV_NRT; i < RECV_NRT + RECV_RT; i ++ ) { pid_recv_rt[i] = fork(); assert( pid_recv_rt[i] >= 0 ); if(0 == pid_recv_rt[i]) { vt->receiver(1); exit(0); } } /* fork senders */ pid_t pid_send_rt[SEND_RT]; for( i = 0; i < SEND_RT; i ++ ) { pid_send_rt[i] = fork(); assert( pid_send_rt[i] >= 0 ); if(0 == pid_send_rt[i]) { vt->sender(); exit(0); } } /* Wait for senders */ for( i = 0; i < SEND_RT; i ++ ) { int status; waitpid( pid_send_rt[i], &status, 0 ); } /* Wait for printer */ { int status; waitpid( pid_print, &status, 0 ); } /* Wait for receivers */ for( i = 0; i < RECV_RT + RECV_NRT; i ++ ) { if( vt == &vtab_pipe ) { kill(pid_recv_rt[i],SIGTERM); } int status; waitpid( pid_recv_rt[i], &status, 0 ); } vt->destroy(); exit(0); }
int main( int argc, char **argv ) { /* Check if we're running under achcop */ if( getenv("ACHCOP") ) { ach_pid_notify = getppid(); } int c; while( (c = getopt( argc, argv, "zlnh?V")) != -1 ) { switch(c) { case 'v': ach_verbosity ++; break; case 'l': opt_last = 1; break; case 'n': opt_last = 0; break; case 'z': opt_gzip = 1; break; /* case 'f': */ /* opt_freq = atof(optarg); */ /* break; */ case 'V': /* version */ ach_print_version("achpipe.bin"); exit(EXIT_SUCCESS); case '?': case 'h': case 'H': puts( "Usage: achlog [OPTIONS] channels...\n" "Log ach channels to files" "\n" "Options:\n" " -?, Show help\n" " -z, Filter output through gzip\n" "\n" "Examples:\n" " achlog foo bar Log channels foo and bar\n" "\n" "Report bugs to <*****@*****.**>" ); exit(EXIT_SUCCESS); default: posarg(optarg); } } while( optind < argc ) { posarg(argv[optind++]); } if( 0 == n_log ) ACH_DIE("No channels to log\n"); /* Block Signals */ /* Have to block these before forking so ctrl-C doesn't kill the * gzip */ int sigs[] = {SIGTERM, SIGINT, 0}; ach_sig_block_dummy( sigs ); /* Open Channels */ size_t i; for( i = 0; i < n_log; i ++ ) { ach_status_t r = ach_open(&log_desc[i].chan, log_desc[i].name, NULL); if( ACH_OK != r ) { ACH_DIE( "Could not open channel %s: %s\n", log_desc[i].name, ach_result_to_string(r) ); } /* Open log file */ if( opt_gzip ) { log_desc[i].fout = filter( "gzip -c", log_desc[i].name, ".gz" ); } else { log_desc[i].fout = fopen(log_desc[i].name, "w"); } if( NULL == log_desc[i].fout ) { ACH_DIE( "Could not open log file for %s: %s\n", log_desc[i].name, strerror(errno) ); } } /* get some data */ if( clock_gettime(ACH_DEFAULT_CLOCK, &now_ach ) || clock_gettime(CLOCK_REALTIME, &now_real ) ) { ACH_DIE( "Could not get time: %s\n", strerror(errno) ); } if( gethostname( host, sizeof(host) ) ) { ACH_LOG(LOG_ERR, "Could not get host name: %s\n", strerror(errno)); } host[sizeof(host)-1] = '\0'; passwd = getpwuid(getuid()); if( passwd ) { strtok(passwd->pw_gecos, ","); } now_real_str = ctime( &now_real.tv_sec ); /* Create Workers */ pthread_t thread[n_log]; for( i = 0; i < n_log; i ++ ) { int r = pthread_create( thread+i, NULL, worker, (void*)(log_desc+i) ); if( r ) ACH_DIE( "Couldn't start worker thread: %s\n", strerror(r) ); } ach_notify(ACH_SIG_OK); /* Wait for Signal */ ach_sig_wait( sigs ); /* Cancel workers */ ach_cancel_attr_t cattr; ach_cancel_attr_init( &cattr ); cattr.async_unsafe = 1; for( i = 0; i < n_log; i ++ ) { ach_cancel( &log_desc[i].chan, &cattr ); } /* Join worker threads */ for( i = 0; i < n_log; i ++ ) { int r = pthread_join( thread[i], NULL ); if( r ) ACH_DIE( "Couldn't join worker thread: %s\n", strerror(r) ); if( opt_gzip ) { if( pclose(log_desc[i].fout) < 0 ) { ACH_LOG( LOG_ERR, "Could not pclose output for %s: %s\n", log_desc[i].name, strerror(errno) ); } } else { fclose(log_desc[i].fout); } } return 0; }
int main( int argc, char **argv ) { /* Parse Options */ int c, i = 0; opterr = 0; while( (c = getopt( argc, argv, "C:U:D:F:vn:m:o:1thH?V")) != -1 ) { switch(c) { case 'C': /* create */ parse_cmd( cmd_create, optarg ); break; case 'U': /* unlink */ parse_cmd( cmd_unlink, optarg ); break; case 'D': /* dump */ parse_cmd( cmd_dump, optarg ); break; case 'F': /* file */ parse_cmd( cmd_file, optarg ); break; case 'n': /* msg-size */ opt_msg_size = (size_t)atoi( optarg ); break; case 'm': /* msg-cnt */ opt_msg_cnt = (size_t)atoi( optarg ); break; case 'o': /* mode */ opt_mode = parse_mode( optarg ); break; case 't': /* truncate */ opt_truncate++; break; case 'v': /* verbose */ opt_verbosity++; break; case '1': /* once */ opt_1++; break; case 'V': /* version */ ach_print_version("ach"); exit(EXIT_SUCCESS); case '?': /* help */ case 'h': case 'H': puts( "Usage: ach [OPTION...] [mk|rm|chmod|dump|file] [mode] [channel-name]\n" "General tool to interact with ach channels\n" "\n" "Options:\n" /* " -C CHANNEL-NAME, Create a new channel\n" */ /* " -U CHANNEL-NAME, Unlink (delete) a channel\n" */ /* " -D CHANNEL-NAME, Dump info about channel\n" */ " -1, With 'mk', accept an already created channel\n" /* " -F CHANNEL-NAME, Print filename for channel (Linux-only)\n" */ " -m MSG-COUNT, Number of messages to buffer\n" " -n MSG-SIZE, Nominal size of a message\n" " -o OCTAL, Mode for created channel\n" " -t, Truncate and reinit newly create channel.\n" " WARNING: this will clobber processes\n" " Currently using the channel.\n" " -v, Make output more verbose\n" " -?, Give program help list\n" " -V, Print program version\n" "\n" "Examples:\n" " ach mk foo Create channel 'foo' with default buffer sizes.\n" " ach mk foo -m 10 -n 256 Create channel 'foo' which can buffer up to 10\n" " messages of nominal size 256 bytes.\n" " Bigger/smaller messages are OK, up to 10*256\n" " bytes max (only one message of that size can be\n" " buffered at a time).\n" " ach rm foo Remove channel 'foo'\n" " ach mk -1 foo Create channel 'foo' unless it already exists,\n" " in which case leave it alone.\n" " ach mk foo -o 600 Create channel 'foo' with octal permissions\n" " '600'. Note that r/w (6) permission necessary\n" " for channel access in order to properly\n" " synchronize.\n" " ach chmod 666 foo Set permissions of channel 'foo' to '666'\n" " ach search foo Search mDNS for host and port of channel 'foo'\n" "\n" "Report bugs to <*****@*****.**>" ); exit(EXIT_SUCCESS); default: posarg(i++, optarg); } } while( optind < argc ) { posarg(i++, argv[optind++]); } /* Be Verbose */ if( opt_verbosity >= 2 ) { fprintf(stderr, "Verbosity: %d\n", opt_verbosity); fprintf(stderr, "Channel Name: %s\n", opt_chan_name); fprintf(stderr, "Message Size: %"PRIuPTR"\n", opt_msg_size); fprintf(stderr, "Message Cnt: %"PRIuPTR"\n", opt_msg_cnt); } /* Do Something */ int r; errno = 0; if( opt_command ) { r = opt_command(); } else if ( opt_chan_name && opt_mode >= 0 ) { r = cmd_chmod(); } else{ fprintf(stderr, "Must specify a command. Say `ach -H' for help.\n"); r = EXIT_FAILURE; } cleanup(); return r; }