struct timespec Yardstick::avg() { return timespec_avg(time_trials); }
int do_work(void * cookie) { dbg_msg("================================================================="); int concurrent_count = fixed_concurent_num ? max_concurrent_proc : random() % (max_concurrent_proc - 1) + 2; proc_id_t pid_arr[concurrent_count]; proc_id_t tpid; bool_t found; int ix; int jx; char strbuff[256]; char * px = strbuff; timespec_t avg_resp_time; timespec_t avg_synchro_time; /* If the critical region is free, elect processes to compete for it */ if (critical_region_is_idle() && concurrent_count > 0) { /* * First collect statistics from last test run */ if (elected_proc_count > 0 && received_resps_count > 0) { dbg_msg("Collecting statistics for test run %d", test_number); if (received_resps_count < elected_proc_count) { dbg_msg("Not all processes finished processing their CS!!! (%u/%u)", received_resps_count, elected_proc_count); } avg_synchro_time = timespec_avg(synchro_delays, received_resps_count); avg_resp_time = timespec_avg(response_times, received_resps_count); dbg_msg("Test %2d: procs=%d avg_synchro_time=%ld.%09lu avg_resp_time=%ld.%09lu", test_number, elected_proc_count, avg_synchro_time.tv_sec, avg_synchro_time.tv_nsec, avg_resp_time.tv_sec, avg_resp_time.tv_nsec); log_msg("Test %2d: procs=%d avg_synchro_time=%ld.%09lu avg_resp_time=%ld.%09lu", test_number, elected_proc_count, avg_synchro_time.tv_sec, avg_synchro_time.tv_nsec, avg_resp_time.tv_sec, avg_resp_time.tv_nsec); /* List the synchronization delays */ memset(strbuff, 0, sizeof(strbuff)); px = strbuff; for (ix = 0; ix < elected_proc_count; ix++) { px += snprintf(px, sizeof(strbuff) - (px - strbuff) - 1, "%3ld.%09lu, ", synchro_delays[ix].tv_sec, synchro_delays[ix].tv_nsec); } dbg_msg("SYNCRO DELAYS: %s", strbuff); log_msg("SYNCRO DELAYS: %s", strbuff); /* List the response times */ memset(strbuff, 0, sizeof(strbuff)); px = strbuff; for (ix = 0; ix < elected_proc_count; ix++) { px += snprintf(px, sizeof(strbuff) - (px - strbuff) - 1, "%3ld.%09lu, ", response_times[ix].tv_sec, response_times[ix].tv_nsec); } dbg_msg("RESPONSE TIMES: %s", strbuff); log_msg("RESPONSE TIMES: %s", strbuff); } else { dbg_msg("Ignoring test run %d (%u of %u responses)", test_number, received_resps_count, elected_proc_count); log_msg("Ignoring test run %d (%u of %u responses)", test_number, received_resps_count, elected_proc_count); } fflush(log_fh); /* * Prepare the test */ elected_proc_count = concurrent_count; received_resps_count = 0; memset(synchro_delays, 0, nodes_count * sizeof(synchro_delays[0])); memset(response_times, 0, nodes_count * sizeof(response_times[0])); clock_gettime(CLOCK_REALTIME, &tstamp_last_exited); test_number++; /* Did we reach the number of tests to perform */ if (test_number > number_of_runs) { handle_event(DME_SEV_ENDSIMULATION, NULL); return 0; } /* Start the test */ dbg_msg("Critical region is free. Starting election process for %d processes.", concurrent_count); /* build the list of competing processes */ ix = 0; while (ix < concurrent_count) { tpid = get_random_pid(); /* Avoid duplicates */ found = FALSE; for(jx = 0; jx < ix && !found; jx++) { if (pid_arr[jx] == tpid) { found = TRUE; } } /* * This process id was not elected before. Add it to the list. * Else replay the loop. */ if (!found) { pid_arr[ix] = tpid; dbg_msg("Elected process %llu", tpid); ix++; } } /* Trigger the elected processes to compete for the critical region */ for (ix = 0; ix < concurrent_count; ix++) { trigger_critical_region(pid_arr[ix], critical_sect_time, 0); nodes[pid_arr[ix]].state = PS_PENDING; } } else { dbg_msg("Critical region is not free yet. Rescheduling."); } /* reschedule this process */ schedule_event(DME_SEV_PERIODIC_WORK, election_interval, 0, NULL); }