Submitted by Doug:

patch #7010: Win32 enhanced bitbang_delay
* bitbang.c (bitbang_calibrate_delay, bitbang_delay): On Win32,
use the high-resolution performance counter rather than the
uneducated delay loop guess if it is available on the target
hardware.




git-svn-id: svn://svn.savannah.nongnu.org/avrdude/trunk/avrdude@894 81a1dc3b-b13d-400b-aceb-764788c761c2
This commit is contained in:
joerg_wunsch 2010-01-08 14:50:22 +00:00
parent e43899b909
commit 9829add3ca
2 changed files with 62 additions and 10 deletions

View File

@ -1,3 +1,12 @@
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Doug:
patch #7010: Win32 enhanced bitbang_delay
* bitbang.c (bitbang_calibrate_delay, bitbang_delay): On Win32,
use the high-resolution performance counter rather than the
uneducated delay loop guess if it is available on the target
hardware.
2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Gerard:

View File

@ -42,7 +42,9 @@
static int delay_decrement;
#if !defined(WIN32NATIVE)
#if defined(WIN32NATIVE)
static int has_perfcount;
#else
static volatile int done;
typedef void (*mysighandler_t)(int);
@ -53,22 +55,46 @@ static void alarmhandler(int signo)
done = 1;
signal(SIGALRM, saved_alarmhandler);
}
#endif /* !WIN32NATIVE */
#endif /* WIN32NATIVE */
/*
* Calibrate the microsecond delay loop below.
*/
static void bitbang_calibrate_delay(void)
{
/*
* Right now, we don't have any Win32 implementation for this, so we
* can only run on a preconfigured delay stepping there. The figure
* below should at least be correct within an order of magnitude,
* judging from the auto-calibration figures seen on various Unix
* systems on comparable hardware.
*/
#if defined(WIN32NATIVE)
delay_decrement = 100;
static LARGE_INTEGER freq;
/*
* If the hardware supports a high-resolution performance counter,
* we ultimately prefer that one, as it gives quite accurate delays
* on modern high-speed CPUs.
*/
if (QueryPerformanceFrequency(&freq))
{
has_perfcount = 1;
if (verbose >= 2)
fprintf(stderr,
"%s: Using performance counter for bitbang delays\n",
progname);
}
else
{
/*
* If a high-resolution performance counter is not available, we
* don't have any Win32 implementation for setting up the
* per-microsecond delay count, so we can only run on a
* preconfigured delay stepping there. The figure below should at
* least be correct within an order of magnitude, judging from the
* auto-calibration figures seen on various Unix systems on
* comparable hardware.
*/
if (verbose >= 2)
fprintf(stderr,
"%s: Using guessed per-microsecond delay count for bitbang delays\n",
progname);
delay_decrement = 100;
}
#else /* !WIN32NATIVE */
struct itimerval itv;
volatile int i;
@ -116,10 +142,27 @@ static void bitbang_calibrate_delay(void)
*/
void bitbang_delay(int us)
{
#if defined(WIN32NATIVE)
LARGE_INTEGER countNow, countEnd;
if (has_perfcount)
{
QueryPerformanceCounter(&countNow);
countEnd.QuadPart = countNow.QuadPart + freq.QuadPart * us / 1000000ll;
while (countNow.QuadPart < countEnd.QuadPart)
QueryPerformanceCounter(&countNow);
}
else /* no performance counters -- run normal uncalibrated delay */
{
#endif /* WIN32NATIVE */
volatile int del = us * delay_decrement;
while (del > 0)
del--;
#if defined(WIN32NATIVE)
}
#endif /* WIN32NATIVE */
}
/*