From 16fd23e787c24e1a55b4ae435c56dce86c7fa6f1 Mon Sep 17 00:00:00 2001 From: Kolja Waschk Date: Tue, 6 Nov 2007 19:59:13 +0000 Subject: [PATCH] [ 1194140 ] SVF better RUNTEST timing git-svn-id: https://urjtag.svn.sourceforge.net/svnroot/urjtag/trunk@705 b68d4a1b-bc3d-0410-92ed-d4ac073336b7 --- jtag/src/svf/svf.c | 158 +++++++++++++++++---------------------------- 1 file changed, 60 insertions(+), 98 deletions(-) diff --git a/jtag/src/svf/svf.c b/jtag/src/svf/svf.c index 4005e1d7..0bb76a57 100644 --- a/jtag/src/svf/svf.c +++ b/jtag/src/svf/svf.c @@ -30,8 +30,11 @@ #include #include #include -#include #include +#include +#include +#include +#include #include "sysdep.h" @@ -549,82 +552,6 @@ svf_all_care(char **string, double number) } -/* - * svf_add_time(start_time, add_secs, result_time) - * - * Adds the given number of seconds to start_time. The reslt is returned - * in result_time. - * start_time and result_time are of type timeval which makes it necessary - * to have a dedicated function for adding a time period to start_time. - * Fractions of add_sec are converted to microseconds and are added to - * start_time accordingly. - * - * Parameter: - * start_time : base time - * add_secs : time to be added to start_time - * floating point value with 1.0 = 1 sec - */ -static void -svf_add_time(struct timeval *start_time, double add_secs, - struct timeval *result_time) -{ - result_time->tv_sec = start_time->tv_sec + (long)floor(add_secs); - result_time->tv_usec = start_time->tv_usec + - (long)((add_secs - floor(add_secs)) * 1000000.0); - - if (result_time->tv_usec > 1000000) { - result_time->tv_usec -= 1000000; - result_time->tv_sec += 1; - } -} - - -/* - * svf_is_later(check, ref) - * - * Compares time check against ref. - * - * Return value: - * 1 : check is later in time than ref - * 0 : otherwise - */ -static int -svf_is_later(struct timeval *check, struct timeval *ref) -{ - int later = 0; - - if (check->tv_sec <= ref->tv_sec) { - if (check->tv_sec == ref->tv_sec) - if (check->tv_usec > ref->tv_usec) - later = 1; - } else - later = 1; - - return(later); -} - - -/* - * svf_is_later_than_now(check) - * - * Compares time check against the current time (aka now). - * - * Return value: - * 1 : check is later than now - * 0 : otherwise - */ -static int -svf_is_later_than_now(struct timeval *check) -{ - struct timeval now; - struct timezone tz = {0, 0}; - - gettimeofday(&now, &tz); - - return(svf_is_later(check, &now)); -} - - /* *************************************************************************** * svf_endxr(ir_dr, state) * @@ -659,7 +586,7 @@ svf_endxr(enum generic_irdr_coding ir_dr, int state) void svf_frequency(double freq) { - frequency = (uint32_t)freq; + cable_set_frequency(chain->cable, freq); } @@ -690,6 +617,13 @@ svf_hxr(enum generic_irdr_coding ir_dr, struct ths_params *params) } +static int max_time_reached; +static void sigalrm_handler(int signal) +{ + max_time_reached = 1; +} + + /* *************************************************************************** * svf_runtest(params) * @@ -705,9 +639,7 @@ svf_hxr(enum generic_irdr_coding ir_dr, struct ths_params *params) int svf_runtest(struct runtest *params) { - int run_count; - struct timeval start_time, min_endtime, max_endtime; - struct timezone tz = {0, 0}; + uint32_t run_count, frequency; /* check for restrictions */ if (params->run_count > 0 && params->run_clk != TCK) { @@ -719,7 +651,12 @@ svf_runtest(struct runtest *params) "svf"); return(0); } - + if (params->max_time > 0.0) + if (!issued_runtest_maxtime) { + printf( _("Warning %s: maximum time for RUNTEST not guaranteed.\n"), "svf"); + printf( _(" This message is only displayed once.\n")); + issued_runtest_maxtime = 1; + } /* update default values for run_state and end_state */ if (params->run_state != 0) { @@ -731,32 +668,57 @@ svf_runtest(struct runtest *params) if (params->end_state != 0) runtest_end_state = svf_map_state(params->end_state); - run_count = (int)(params->run_count); + /* compute run_count */ + run_count = params->run_count; + frequency = cable_get_frequency(chain->cable); + if (frequency > 0) { + uint32_t min_time_run_count = ceil(params->min_time / frequency); + if (min_time_run_count > run_count) { + run_count = min_time_run_count; + } + } + assert(run_count > 0); svf_goto_state(runtest_run_state); - /* init timing */ - if (params->max_time > 0.0) - if (!issued_runtest_maxtime) { - printf( _("Warning %s: maximum time for RUNTEST not guaranteed.\n"), "svf"); - printf( _(" This message is only displayed once.\n")); - issued_runtest_maxtime = 1; + /* set up the timer for max_time */ + if (params->max_time > 0.0) { + struct sigaction sa; + unsigned max_time; + + sa.sa_handler = sigalrm_handler; + sa.sa_flags = SA_ONESHOT; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) != 0) { + perror("sigaction"); + exit(EXIT_FAILURE); } - gettimeofday(&start_time, &tz); - svf_add_time(&start_time, params->min_time, &min_endtime); - svf_add_time(&start_time, params->max_time, &max_endtime); - while (run_count > 0 || svf_is_later_than_now(&min_endtime)) { - chain_clock(chain, 0, 0); - run_count--; + max_time = floor(params->max_time / 1000000); + if (max_time == 0) { + max_time = 1; + } + ualarm(max_time, 0); + } - if (svf_is_later(&max_endtime, &start_time)) - if (!svf_is_later_than_now(&max_endtime)) - break; + while (run_count-- > 0 && !max_time_reached) { + chain_clock(chain, 0, 0); } svf_goto_state(runtest_end_state); + /* stop the timer */ + if (params->max_time > 0.0) { + struct sigaction sa; + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + sigemptyset(&sa.sa_mask); + if (sigaction(SIGALRM, &sa, NULL) != 0) { + perror("sigaction"); + exit(EXIT_FAILURE); + } + } + return(1); }