static int stats_file_history_update(struct stats_file *data_file) { struct stats_file _history_file, *history_file; struct stats_file _temp_file, *temp_file; int err; history_file = &_history_file; temp_file = &_temp_file; bzero(history_file, sizeof(struct stats_file)); bzero(temp_file, sizeof(struct stats_file)); err = stats_open(history_file, data_file->history_name); if (err < 0) return err; stats_file_setup(history_file); err = stats_open_temp(temp_file); if (err < 0) { stats_free(history_file); return err; } stats_file_setup(temp_file); summarize(data_file, history_file, temp_file); err = stats_file_close_swap(history_file, temp_file); return err; }
codestats_t* code_get_statistics(code_t*code, abc_exception_list_t*exceptions) { currentstats_t*current = code_get_stats(code, exceptions); if(!current) return 0; codestats_t*stats = rfx_calloc(sizeof(codestats_t)); stats->local_count = current->maxlocal; stats->max_stack = current->maxstack; stats->max_scope_depth = current->maxscope; stats->flags = current->flags; stats_free(current);current=0; return stats; }
static struct stats *open_stats(const char *name) { struct stats *stats = NULL; int err; err = stats_create(name,&stats); if (err != S_OK) { printf("Failed to create stats: %s\n", error_message(err)); return NULL; } err = stats_open(stats); if (err != S_OK) { printf("Failed to open stats: %s\n", error_message(err)); stats_free(stats); return NULL; } return stats; }
int main(int argc, char **argv) { struct context ctx = {0}; struct event *signal_int; struct evhttp_bound_socket *handle; char listen_addr[256]; if (argc != 2) { printf("usage: statsrv STATS\n"); return -1; } if (stats_cl_create(&ctx.cl) != S_OK) { printf("Failed to allocate stats counter list\n"); return ERROR_FAIL; } if (stats_sample_create(&ctx.sample) != S_OK) { printf("Failed to allocate stats sample\n"); return ERROR_FAIL; } if (stats_sample_create(&ctx.prev_sample) != S_OK) { printf("Failed to allocate stats sample\n"); return ERROR_FAIL; } ctx.stats = open_stats(argv[1]); if (!ctx.stats) { printf("Failed to open stats %s\n", argv[1]); return ERROR_FAIL; } ctx.base = event_base_new(); if (!ctx.base) { printf("Could not allocate event base\n"); return 1; } /* add a handler for SIGINT */ signal_int = evsignal_new(ctx.base, SIGINT, sigint_cb, event_self_cbarg()); evsignal_add(signal_int,0); /* Create a new evhttp object to handle requests. */ ctx.http = evhttp_new(ctx.base); if (!ctx.http) { printf("could not create evhttp.\n"); return ERROR_FAIL; } evhttp_set_gencb(ctx.http, http_request_cb, &ctx); /* Now we tell the evhttp what port to listen on */ handle = evhttp_bind_socket_with_handle(ctx.http, "0.0.0.0", 8080); if (!handle) { printf("couldn't bind to http port %d.\n", (int)8080); return ERROR_FAIL; } if (http_get_address(handle, listen_addr, sizeof(listen_addr)) == S_OK) printf("http: listening at %s\n", listen_addr); event_base_dispatch(ctx.base); event_free(signal_int); #if 0 start_time = current_time(); while (!signal_received) { err = stats_get_sample(stats,cl,sample); if (err != S_OK) { printf("Error %08x (%s) getting sample\n",err,error_message(err)); } clear(); sample_time = TIME_DELTA_TO_NANOS(start_time, sample->sample_time); mvprintw(0,0,"SAMPLE @ %6lld.%03llds SEQ:%d\n", sample_time / 1000000000ll, (sample->sample_time % 1000000000ll) / 1000000ll, sample->sample_seq_no); n = 1; maxy = getmaxy(stdscr); col = 0; for (j = 0; j < cl->cl_count; j++) { counter_get_key(cl->cl_ctr[j],counter_name,MAX_COUNTER_KEY_LENGTH+1); mvprintw(n,col+0,"%s", counter_name); mvprintw(n,col+29,"%15lld", stats_sample_get_value(sample,j)); mvprintw(n,col+46,"%15lld", stats_sample_get_delta(sample,prev_sample,j)); if (++n == maxy) { col += 66; n = 1; } } refresh(); tmp = prev_sample; prev_sample = sample; sample = tmp; FD_ZERO(&fds); FD_SET(0,&fds); now = current_time(); tv.tv_sec = 0; tv.tv_usec = 1000000 - (now % 1000000000) / 1000; ret = select(1, &fds, NULL, NULL, &tv); if (ret == 1) { ch = getch(); if (ch == 'c' || ch == 'C') { stats_reset_counters(stats); } } } close_screen(); #endif if (ctx.base) event_base_free(ctx.base); if (ctx.http) evhttp_free(ctx.http); if (ctx.stats) { stats_close(ctx.stats); stats_free(ctx.stats); } if (ctx.cl) stats_cl_free(ctx.cl); if (ctx.sample) stats_sample_free(ctx.sample); if (ctx.prev_sample) stats_sample_free(ctx.prev_sample); return 0; }
int code_dump2(code_t*c, abc_exception_list_t*exceptions, abc_file_t*file, char*prefix, FILE*fo) { abc_exception_list_t*e = exceptions; c = code_start(c); currentstats_t*stats = code_get_stats(c, exceptions); int pos = 0; while(c) { U8 opcode = c->opcode; char found = 0; opcode_t*op = opcode_get(opcode); e = exceptions; while(e) { if(c==e->abc_exception->from) fprintf(fo, "%s TRY {\n", prefix); if(c==e->abc_exception->target) { char*s1 = multiname_tostring(e->abc_exception->exc_type); char*s2 = multiname_tostring(e->abc_exception->var_name); fprintf(fo, "%s CATCH(%s %s)\n", prefix, s1, s2); free(s1); free(s2); } e = e->next; } if(!op) { fprintf(stderr, "Can't parse opcode %02x.\n", opcode); return 0; } else { char*p = op->params; char first = 1; int i=0; if(stats) { int f = stats->stack[c->pos].flags; fprintf(fo, "%s%05d) %c %d:%d %s ", prefix, c->pos, (f&FLAG_ERROR)?'E':((f&FLAG_SEEN)?'+':'|'), stats->stack[c->pos].stackpos, stats->stack[c->pos].scopepos, op->name); } else { fprintf(fo, "%s%05d) ? ?:? %s ", prefix, c->pos, op->name); } while(*p) { void*data = c->data[i]; if(i>0) printf(", "); if(*p == 'n') { int n = (ptroff_t)data; fprintf(fo, "%d params", n); } else if(*p == '2') { multiname_t*n = (multiname_t*)data; char* m = multiname_tostring(n); fprintf(fo, "%s", m); free(m); } else if(*p == 'N') { namespace_t*ns = (namespace_t*)data; char* m = namespace_tostring(ns); fprintf(fo, "%s", m); free(m); } else if(*p == 'm') { abc_method_t*m = (abc_method_t*)data; fprintf(fo, "[method %08x %s]", m->index, m->name); } else if(*p == 'c') { abc_class_t*cls = (abc_class_t*)data; char*classname = multiname_tostring(cls->classname); fprintf(fo, "[classinfo %08x %s]", cls->index, classname); free(classname); } else if(*p == 'i') { abc_method_body_t*b = (abc_method_body_t*)data; fprintf(fo, "[methodbody]"); } else if(*p == 'u' || *p == 'I' || *p == 'U') { int n = (ptroff_t)data; fprintf(fo, "%d", n); } else if(*p == 'f') { double f = *(double*)data; fprintf(fo, "%f", f); } else if(*p == 'r') { int n = (ptroff_t)data; fprintf(fo, "r%d", n); } else if(*p == 'b') { int b = (signed char)(ptroff_t)data; fprintf(fo, "%d", b); } else if(*p == 'j') { if(c->branch) fprintf(fo, "->%d", c->branch->pos); else fprintf(fo, "%08x", (unsigned int)c->branch); } else if(*p == 's') { char*s = string_escape((string_t*)data); fprintf(fo, "\"%s\"", s); free(s); } else if(*p == 'D') { fprintf(fo, "[register %02x=%s]", (ptroff_t)c->data[1], (char*)c->data[0]); } else if(*p == 'S') { lookupswitch_t*l = c->data[0]; fprintf(fo, "["); if(l->def) fprintf(fo, "default->%d", l->def->pos); else fprintf(fo, "default->00000000"); code_list_t*t = l->targets; while(t) { if(t->code) fprintf(fo, ",->%d", t->code->pos); else fprintf(fo, ",->00000000"); t = t->next; } fprintf(fo, "]"); } else { fprintf(stderr, "Can't parse opcode param type \"%c\"\n", *p); return 0; } p++; i++; first = 0; } fprintf(fo, "\n"); } e = exceptions; while(e) { if(c==e->abc_exception->to) { if(e->abc_exception->target) fprintf(fo, "%s } // END TRY (HANDLER: %d)\n", prefix, e->abc_exception->target->pos); else fprintf(fo, "%s } // END TRY (HANDLER: 00000000)\n", prefix); } e = e->next; } pos++; c = c->next; } stats_free(stats); return 1; }
int init(const platform_env_t* env) { paused = 0; LOGI("Environment:\n Platform: %d\n Assets: %s\n Shared: %s\n Config: %s\n Tmp: %s\n", env->platform, env->assets_dir, env->shared_dir, env->config_dir, env->tmp_dir); io_driver_t* assets = NULL; io_driver_t* config = NULL; io_driver_t* tmp = NULL; io_driver_t* shared = NULL; if (io_init(&io) != 0 || #ifdef ANDROID io_driver_apk_init(&assets, env->platform_specific) != 0 || #else io_driver_fs_init(&assets, env->assets_dir) != 0 || #endif io_driver_fs_init(&config, env->config_dir) != 0 || io_driver_fs_init(&shared, env->shared_dir) != 0 || io_driver_fs_init(&tmp, env->tmp_dir) != 0 || io_bind(io, "/config", config) || io_bind(io, "/tmp", tmp) || io_bind(io, "/shared", shared) || io_bind(io, "/assets", assets) ) { LOGE("Error initializing I/O system"); return -1; } io_set_working_dir(io, "/assets"); io_set_default(io); if (gfx_init(&gfx) != 0) { LOGE("Error initializing GFX system"); return -1; } font_info_t info = { .name = "fonts/default.ttf", .face_index = 0, .width = 0, .height = 14 * 64, .dpi_x = 0, .dpi_y = 72, }; if (font_init(&font, &info, NULL) != 0) { LOGE("Error loading font"); return -1; } info.height = 22 * 64; if (font_init(&big_font, &info, NULL) != 0) { LOGE("Error loading font"); return -1; } if (atlases_load(&atlases, "atlases.dat") != 0) { LOGE("Error loading atlases metadata"); return -1; } if (sprites_load(&sprites, "sprites.dat") != 0) { LOGE("Error loading sprites metadata"); return -1; } stats_load(&global_stats, "/config/player.dat"); if (am_init(&am, achievements_get_all(), achievements_get_count(), achievement_progress, achievement_unlocked)) { LOGE("Unable to initialize achievements manager"); return -1; } achievements_context.am = am; am_load(am, "/config/achievements.dat"); timestamp_set(&timer); timestamp_set(&fps_timer); push_screen(SCREEN_MAIN_MENU); return 0; } void shutdown() { LOGI("shutdown"); atlases_free(atlases); sprites_free(sprites); font_free(font); font_free(big_font); gfx_free(gfx); stats_dump(&global_stats); stats_save(&global_stats, "/config/player.dat"); stats_free(&global_stats); if (am != NULL) { am_save(am, "/config/achievements.dat"); am_dump(am); am_free(am); am = NULL; } io_free(io); io = NULL; atlases = NULL; sprites = NULL; font = NULL; big_font = NULL; gfx = NULL; }
int main(int argc, char **argv) { struct addrinfo *addrs, *addr; char *host = "127.0.0.1"; char *port = "1337"; int rc; // for checking that the server's up char poke[SHA_LENGTH * 2]; tinymt64_t rando; if (parse_args(&cfg, &host, &port, argc, argv)) { usage(); exit(1); } struct addrinfo hints = { .ai_family = AF_UNSPEC, .ai_socktype = SOCK_STREAM }; if ((rc = getaddrinfo(host, port, &hints, &addrs)) != 0) { const char *msg = gai_strerror(rc); fprintf(stderr, "unable to resolve %s:%s: %s\n", host, port, msg); exit(1); } for (addr = addrs; addr != NULL; addr = addr->ai_next) { int fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol); if (fd == -1) continue; rc = connect(fd, addr->ai_addr, addr->ai_addrlen); tinymt64_init(&rando, time_us()); random_hash(&rando, poke); if (rc == 0 && write(fd, poke, SHA_LENGTH * 2) == SHA_LENGTH * 2) { read(fd, poke, SHA_LENGTH * 2); close(fd); break; } close(fd); } if (addr == NULL) { char *msg = strerror(errno); fprintf(stderr, "unable to connect to %s:%s: %s\n", host, port, msg); exit(1); } signal(SIGPIPE, SIG_IGN); signal(SIGINT, SIG_IGN); cfg.addr = *addr; pthread_mutex_init(&statistics.mutex, NULL); statistics.latency = stats_alloc(SAMPLES); statistics.requests = stats_alloc(SAMPLES); thread *threads = zcalloc(cfg.threads * sizeof(thread)); uint64_t connections = cfg.connections / cfg.threads; uint64_t stop_at = time_us() + (cfg.duration * 1000000); for (uint64_t i = 0; i < cfg.threads; i++) { thread *t = &threads[i]; t->connections = connections; t->stop_at = stop_at; if (pthread_create(&t->thread, NULL, &thread_main, t)) { char *msg = strerror(errno); fprintf(stderr, "unable to create thread %"PRIu64" %s\n", i, msg); exit(2); } } struct sigaction sa = { .sa_handler = handler, .sa_flags = 0, }; sigfillset(&sa.sa_mask); sigaction(SIGINT, &sa, NULL); char *time = format_time_s(cfg.duration); printf("Running %s test @ %s:%s\n", time, host, port); printf(" %"PRIu64" threads and %"PRIu64" connections\n", cfg.threads, cfg.connections); uint64_t start = time_us(); uint64_t complete = 0; uint64_t bytes = 0; errors errors = { 0 }; for (uint64_t i = 0; i < cfg.threads; i++) { thread *t = &threads[i]; pthread_join(t->thread, NULL); complete += t->complete; bytes += t->bytes; errors.connect += t->errors.connect; errors.handshake += t->errors.handshake; errors.read += t->errors.read; errors.validate += t->errors.validate; errors.write += t->errors.write; errors.timeout += t->errors.timeout; } uint64_t runtime_us = time_us() - start; long double runtime_s = runtime_us / 1000000.0; long double req_per_s = complete / runtime_s; long double bytes_per_s = bytes / runtime_s; print_stats_header(); print_stats("Latency", statistics.latency, format_time_us); print_stats("Req/Sec", statistics.requests, format_metric); if (cfg.latency) print_stats_latency(statistics.latency); char *runtime_msg = format_time_us(runtime_us); printf(" %"PRIu64" requests in %s, %sB read\n", complete, runtime_msg, format_binary(bytes)); if (errors.connect || errors.read || errors.write || errors.timeout) { printf(" Socket errors: connect %d, read %d, write %d, timeout %d\n", errors.connect, errors.read, errors.write, errors.timeout); } if (errors.handshake) { printf(" Bad handshakes from server: %d\n", errors.handshake); } if (errors.validate) { printf(" %d proofs failed verification.\n", errors.validate); } printf("Requests/sec: %9.2Lf\n", req_per_s); printf("Transfer/sec: %10sB\n", format_binary(bytes_per_s)); return 0; } void *thread_main(void *arg) { thread *thread = arg; aeEventLoop *loop = aeCreateEventLoop(10 + cfg.connections * 3); thread->cs = zmalloc(thread->connections * sizeof(connection)); thread->loop = loop; tinymt64_init(&thread->rand, time_us()); thread->latency = stats_alloc(100000); connection *c = thread->cs; for (uint64_t i = 0; i < thread->connections; i++, c++) { c->thread = thread; random_hash(&thread->rand, c->hash); connect_socket(thread, c); } aeCreateTimeEvent(loop, CALIBRATE_DELAY_MS, calibrate, thread, NULL); aeCreateTimeEvent(loop, TIMEOUT_INTERVAL_MS, check_timeouts, thread, NULL); thread->start = time_us(); aeMain(loop); aeDeleteEventLoop(loop); zfree(thread->cs); uint64_t max = thread->latency->max; stats_free(thread->latency); pthread_mutex_lock(&statistics.mutex); for (uint64_t i = 0; i < thread->missed; i++) { stats_record(statistics.latency, max); } pthread_mutex_unlock(&statistics.mutex); return NULL; }
int main (int argc, char **argv) { List nflist; int summary = FALSE; int error_occurred = FALSE; struct stats *total_stats = stats_alloc (); int processed = 0; int opt; int option_index = 0; extern char *optarg; extern int optind, opterr, optopt; struct option long_options[] = { {"debug",0,0,'D'}, {"summary",0,0,'s'}, {"help",0,0,'h'}, {"version",0,0,0}, {0,0,0,0} }; #ifdef __GLIBC__ program_name = program_invocation_short_name; #else program_name = base_name (argv[0]); #endif /* Initialize i18n. */ #ifdef HAVE_SETLOCALE setlocale (LC_ALL, ""); #endif #if ENABLE_NLS bindtextdomain (PACKAGE, LOCALEDIR); textdomain (PACKAGE); #endif setup (); while ((opt = getopt_long (argc, argv, "sh", long_options, &option_index)) != -1) { switch (opt) { case 0: { printf_version_string (N_("nfstats")); teardown (); if (fclose (stdout) == EOF) error (EXIT_FAILURE, errno, _("error writing output")); exit (EXIT_SUCCESS); } case 'D': debug = TRUE; break; case 's': summary = TRUE; break; case 'h': printf (_("Usage: %s [OPTION]... NOTESFILE...\n" "Display usage statistics for NOTESFILE(s), including a total.\n\n"), program_name); printf (_(" -s, --summary Print only the total for all listed notesfiles\n" " --debug Display debugging messages\n\n" " -h, --help Display this help and exit\n" " --version Display version information and exit\n\n")); printf (_("Report bugs to <%s>.\n"), PACKAGE_BUGREPORT); teardown (); if (fclose (stdout) == EOF) error (EXIT_FAILURE, errno, _("error writing output")); exit (EXIT_SUCCESS); case '?': fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name); teardown (); exit (EXIT_FAILURE); } } if (optind == argc) { fprintf (stderr, _("%s: too few arguments\n"), program_name); fprintf (stderr, _("Try '%s --help' for more information.\n"), program_name); teardown (); exit (EXIT_FAILURE); } list_init (&nflist, (void * (*) (void)) nfref_alloc, (void (*) (void *)) nfref_free, NULL); while (optind < argc) parse_nf (argv[optind++], &nflist); { ListNode *node = list_head (&nflist); struct stats *stats = stats_alloc (); while (node != NULL && !error_occurred) { newts_nfref *ref = (newts_nfref *) list_data (node); int result = get_stats (ref, stats); if (result != NEWTS_NO_ERROR) { fprintf (stderr, _("%s: error getting stats for '%s'\n"), program_name, nfref_pretty_name (ref)); error_occurred = TRUE; break; } if (!summary) { if (processed) printf ("\n"); printf (_("Usage statistics for %s\n"), nfref_pretty_name (ref)); printf (_(" NOTES RESPS TOTALS\n")); printf (_("Local Reads: %7u %7u %7u\n"), stats->notes_read, stats->resps_read, (stats->notes_read + stats->resps_read)); printf (_("Local Writes: %7u %7u %7u\n"), (stats->notes_written - stats->notes_received), (stats->resps_written - stats->resps_received), (stats->notes_written + stats->resps_written - stats->notes_received - stats->resps_received)); printf (_("Entries into Notesfile: %u\n"), stats->entries); printf (_("Total Time in Notesfile: %.2f minutes\n"), ((float) stats->total_time / 60.0)); if (stats->entries) printf (_("Average Time/Entry: %.2f minutes\n"), (((float) stats->total_time / 60.0) / (float) stats->entries)); } stats_accumulate (stats, total_stats); processed++; node = list_next (node); } stats_free (stats); } if (processed && (summary || processed != 1) && !error_occurred) { if (!summary) printf ("\n"); printf (_("Total for all requested notesfiles\n")); printf (_(" NOTES RESPS TOTALS\n")); printf (_("Local Reads: %7u %7u %7u\n"), total_stats->notes_read, total_stats->resps_read, (total_stats->notes_read + total_stats->resps_read)); printf (_("Local Writes: %7u %7u %7u\n"), (total_stats->notes_written - total_stats->notes_received), (total_stats->resps_written - total_stats->resps_received), (total_stats->notes_written + total_stats->resps_written - total_stats->notes_received - total_stats->resps_received)); printf (_("Entries into Notesfiles: %u\n"), total_stats->entries); printf (_("Total Time in Notesfiles: %.2f minutes\n"), ((float) total_stats->total_time / 60.0)); if (total_stats->entries) printf (_("Average Time/Entry: %.2f minutes\n"), (((float) total_stats->total_time / 60.0) / (float) total_stats->entries)); } stats_free (total_stats); list_destroy (&nflist); teardown (); if (fclose (stdout) == EOF) error (EXIT_FAILURE, errno, _("error writing output")); exit (error_occurred ? EXIT_FAILURE : EXIT_SUCCESS); }
static int showStats(int operandLen, char *operand[], cmdOptions_t *options) { char *first_str = NULL; char scale_buf[16]; tgt_node_t *node, *n1; int interval = -1; int count = -1; int header; stat_delta_t cur_data, *pd; tgt_buf_add_tag(&first_str, "list", Tag_Start); tgt_buf_add_tag(&first_str, XML_ELEMENT_TARG, Tag_Start); tgt_buf_add(&first_str, XML_ELEMENT_IOSTAT, OPT_TRUE); if (operandLen) tgt_buf_add(&first_str, XML_ELEMENT_NAME, operand[0]); for (; options->optval; options++) { switch (options->optval) { case 0: break; case 'I': /* optarg = refresh interval */ interval = atoi(options->optarg); if (interval == 0) { (void) fprintf(stderr, "%s: %s\n", cmdName, gettext("interval must be non-zero")); free(first_str); return (1); } break; case 'N': count = atoi(options->optarg); if (count == 0) { (void) fprintf(stderr, "%s: %s\n", cmdName, gettext("count must be non-zero")); free(first_str); return (1); } break; default: (void) fprintf(stderr, "%s: %c: %s\n", cmdName, options->optval, gettext("unknown option")); free(first_str); return (1); } } tgt_buf_add_tag(&first_str, XML_ELEMENT_TARG, Tag_End); tgt_buf_add_tag(&first_str, "list", Tag_End); header = 1; /*CONSTANTCONDITION*/ while (1) { if (--header == 0) { (void) printf("%20s %12s %12s\n", " ", gettext("operations"), gettext("bandwidth ")); (void) printf("%-20s %5s %5s %5s %5s\n", gettext("device"), gettext("read"), gettext("write"), gettext("read"), gettext("write")); (void) printf("%-20s %5s %5s %5s %5s\n", "--------------------", "-----", "-----", "-----", "-----"); header = 20; } if ((node = tgt_door_call(first_str, 0)) == NULL) { (void) fprintf(stderr, "%s: %s\n", cmdName, gettext("No reponse from daemon")); return (1); } if (strcmp(node->x_name, XML_ELEMENT_RESULT)) { (void) fprintf(stderr, "%s: %s\n", cmdName, gettext("Bad XML response")); free(first_str); tgt_node_free(node); stats_free(); return (1); } n1 = NULL; while (n1 = tgt_node_next_child(node, XML_ELEMENT_TARG, n1)) { stats_load_counts(n1, &cur_data); if ((pd = stats_prev_counts(&cur_data)) == NULL) { free(first_str); tgt_node_free(node); return (1); } (void) printf("%-20s ", pd->device); (void) printf("%5s ", number_to_scaled_string(scale_buf, cur_data.read_cmds - pd->read_cmds, 1, 1024)); (void) printf("%5s ", number_to_scaled_string(scale_buf, cur_data.write_cmds - pd->write_cmds, 1, 1024)); (void) printf("%5s ", number_to_scaled_string(scale_buf, cur_data.read_blks - pd->read_blks, 512, 1024)); (void) printf("%5s\n", number_to_scaled_string(scale_buf, cur_data.write_blks - pd->write_blks, 512, 1024)); stats_update_counts(pd, &cur_data); } tgt_node_free(node); if (count == -1) { if (interval == -1) /* No count or internal, do it just once */ break; else (void) sleep(interval); } else if (--count) { if (interval == -1) break; else (void) sleep(interval); } else break; } stats_free(); free(first_str); return (0); }