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 c7f93ef7f1
commit 0433f5e8ef
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> 2010-01-08 Joerg Wunsch <j.gnu@uriah.heep.sax.de>
Submitted by Gerard: Submitted by Gerard:

View File

@ -42,7 +42,9 @@
static int delay_decrement; static int delay_decrement;
#if !defined(WIN32NATIVE) #if defined(WIN32NATIVE)
static int has_perfcount;
#else
static volatile int done; static volatile int done;
typedef void (*mysighandler_t)(int); typedef void (*mysighandler_t)(int);
@ -53,22 +55,46 @@ static void alarmhandler(int signo)
done = 1; done = 1;
signal(SIGALRM, saved_alarmhandler); signal(SIGALRM, saved_alarmhandler);
} }
#endif /* !WIN32NATIVE */ #endif /* WIN32NATIVE */
/* /*
* Calibrate the microsecond delay loop below. * Calibrate the microsecond delay loop below.
*/ */
static void bitbang_calibrate_delay(void) 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) #if defined(WIN32NATIVE)
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; delay_decrement = 100;
}
#else /* !WIN32NATIVE */ #else /* !WIN32NATIVE */
struct itimerval itv; struct itimerval itv;
volatile int i; volatile int i;
@ -116,10 +142,27 @@ static void bitbang_calibrate_delay(void)
*/ */
void bitbang_delay(int us) 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; volatile int del = us * delay_decrement;
while (del > 0) while (del > 0)
del--; del--;
#if defined(WIN32NATIVE)
}
#endif /* WIN32NATIVE */
} }
/* /*