int stats_update(int type, strand_t *s, newstats_t *stats, uint64_t size, uint64_t count) { if (DISABLED_STATS(options)) return (0); switch (type) { case FLOWOP_BEGIN: if (ENABLED_FLOWOP_STATS(options) || ENABLED_HISTORY_STATS(options)) { return (newstat_begin(s, stats, 0, 0)); } return (0); case FLOWOP_END: /* We update the strand stats instead of having a global one */ STRAND_STAT(s)->size += size*count; /* Thread safe */ STRAND_STAT(s)->count += count; /* Thread safe */ if (ENABLED_FLOWOP_STATS(options) || ENABLED_HISTORY_STATS(options)) { int err = newstat_end(s, stats, size, count); if (ENABLED_HISTORY_STATS(options)) { history_record(s, NSTAT_FLOWOP, stats->end_time, stats->end_time - stats->time_used_start); } return (err); } return (0); case TXN_BEGIN: if (ENABLED_TXN_STATS(options)) return (newstat_begin(s, stats, 0, 0)); return (0); case GROUP_BEGIN: if (ENABLED_GROUP_STATS(options)) return (newstat_begin(s, stats, 0, 0)); return (0); case TXN_END: if (ENABLED_TXN_STATS(options)) return (newstat_end(s, stats, 0, count)); return (0); case GROUP_END: if (ENABLED_GROUP_STATS(options)) return (newstat_end(s, stats, 0, count)); return (0); } return (0); }
int master(workorder_t *w) { int rc; int i; int thr_count; int nthr, nproc; int id; int goodbye_timeout = UPERF_GOODBYE_TIMEOUT; hrtime_t start, stop; uperf_shm_t *shm; goodbye_stat_t gtotal; int error; if ((shm = master_init(w)) == NULL) exit(1); /* * We need to get the total number of threads to arm the * start, and end barriers. */ nproc = workorder_num_strands_bytype(w, STRAND_TYPE_PROCESS); nthr = workorder_num_strands_bytype(w, STRAND_TYPE_THREAD); thr_count = nproc + nthr; if (handshake(shm, w) != UPERF_SUCCESS) { uperf_info("Error in handshake\n"); shm_fini(shm); exit(1); } if (nthr == 0 && nproc != 0) { (void) printf("Starting %d processes running profile:%s ... ", thr_count, w->name); } else if (nproc == 0 && nthr != 0) { (void) printf("Starting %d threads running profile:%s ... ", thr_count, w->name); } else { (void) printf( "Starting %d threads, %d processes running profile:%s ... ", nthr, nproc, w->name); } (void) fflush(stdout); start = GETHRTIME(); /* Traverse through the worklist and create threads */ id = 0; for (i = 0; i < w->ngrp; i++) { w->grp[i].groupid = i; if (shm->global_error > 0) break; if (spawn_strands_group(shm, &w->grp[i], id) != 0) shm->global_error++; id += w->grp[i].nthreads; } if (shm->global_error > 0) { master_prepare_to_exit(shm); shm_fini(shm); return (UPERF_FAILURE); } stop = GETHRTIME(); (void) printf(" %5.2f seconds\n", (stop-start)/1.0e+9); (void) fflush(stdout); /* Handshake end */ if (handshake_end_master(shm, w) != UPERF_SUCCESS) { return (UPERF_FAILURE); } #ifdef ENABLE_NETSTAT if (ENABLED_PACKET_STATS(options)) netstat_snap(SNAP_BEGIN); #endif /* ENABLE_NETSTAT */ /* * The main Loop. * if either global_error is not 0 or master_poll returns 1 * let wait_for_strands know that. */ newstat_begin(0, AGG_STAT(shm), 0, 0); error = master_poll(shm); if (error == 0 && shm->global_error != 0) error = shm->global_error; (void) wait_for_strands(shm, error); newstat_end(0, AGG_STAT(shm), 0, 0); shm->current_time = GETHRTIME(); #ifdef ENABLE_NETSTAT if (ENABLED_PACKET_STATS(options)) netstat_snap(SNAP_END); #endif /* ENABLE_NETSTAT */ if (ENABLED_STATS(options)) { print_summary(AGG_STAT(shm), 0); } if (shm->global_error > 0) { /* decrease timeout coz no point in waiting */ goodbye_timeout = 1000; } if (ENABLED_GROUP_STATS(options)) print_group_details(shm); if (ENABLED_THREAD_STATS(options)) print_strand_details(shm); if (ENABLED_TXN_STATS(options)) print_txn_averages(shm); if (ENABLED_FLOWOP_STATS(options)) print_flowop_averages(shm); #ifdef ENABLE_NETSTAT if (ENABLED_PACKET_STATS(options)) print_netstat(); #endif /* ENABLE_NETSTAT */ if (ENABLED_ERROR_STATS(options)) { goodbye_stat_t local; (void) memset(>otal, 0, sizeof (goodbye_stat_t)); if ((rc = say_goodbyes_and_close(>otal, goodbye_timeout)) == 0) { update_aggr_stat(shm); local.elapsed_time = (AGG_STAT(shm))->end_time - (AGG_STAT(shm))->start_time; local.error = 0; local.bytes_xfer = (AGG_STAT(shm))->size; local.count = (AGG_STAT(shm))->count; print_goodbye_stat("master", &local); print_difference(local, gtotal); } } uperf_log_flush(); if (ENABLED_HISTORY_STATS(options)) { (void) fclose(options.history_fd); } /* Cleanup */ if (shm->global_error != 0) { (void) printf("\nWARNING: Errors detected during run\n"); shm_fini(shm); exit(1); } shm_fini(shm); return (rc); }