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:
parent
e43899b909
commit
9829add3ca
|
@ -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:
|
||||
|
|
63
bitbang.c
63
bitbang.c
|
@ -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 */
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in New Issue