⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 uclock.c

📁 国外网站上的一些精典的C程序
💻 C
字号:
/***  UCLOCK.C****  Contains routines to perform microsecond accuracy timing**  operations.****  Adapted from free sources originally by:**  Kris Heidenstrom (kheidens@actrix.gen.nz)****  For additional information, ftp:**  oak.oakland.edu//SimTel/msdos/info/pctim*.zip.****  Modified by Bob Stout (see UCLOCK_.ASM)*/#include <stddef.h>#include <assert.h>#include "uclock.h"#include "cast.h"#include "snpdosys.h"/***  usec_clock()****  An analog of the standard clock() function, usec_clock() returns a**  uclock_t value (defined in UCLOCK.H) which represents the number**  of clock ticks past midnight. Analogous to CLK_TCK is UCLK_TCK, the**  number which a usec_clock() reading must be divided by to yield**  a number of seconds.****  Parameters: 1 - Pointer to a Uclock_T structure to be filled in. If**                  NULL, an auto buffer is used.****  Returns: If NULL is passed, returns uclock_t ticks since last midnight.**           If a Uclock_T pointer was passed, returns -1.0.****  Side effects: Reprograms timer channel 0 to mode 2. This is a benign**                change with no known harmful effects on any normally**                PC-compatible hardware. Note that although most early**                PC's, XT's, and AT's typically run timer channel 0 in**                mode 3, later model AT compatibles including many 386,**                486, and Pentium systems already use mode 2.****  Notes: Under Windows or OS/2 (HW_TIMER must be turned on), results are**         generally unreliable due to the fact that there can be a**         considerable and unpredictable lag between the time when the**         virtual machine rolls over the virtual CTC registers the time**         when the BIOS data area is updated. As a compromise, usec_clock()**         detects when running in a non-DOS environment and retries until**         it achieves monotonically increasing readings. This results in**         an effective resolution much coarser than the .8381 uSec.**         achieved under DOS. Although the result will still contain**         20-bit data, the actual resolution will be lower and dependent**         upon system speed, loading, and other overhead factors.*/uclock_t usec_clock(Uclock_T *now){      static int init = 0;      Uclock_T buf, *ptr;      if (NULL == now)            ptr = &buf;      else  ptr = now;      if (!init)                          /* Only reprogram CTC once!   */      {            SetMode2_();            init = -1;      }      Uclock_(ptr);      /*      ** If Win or OS/2, ticks may lag CTC rollover so wait for      ** monotonically increasing readings.      */      if (DOS != get_os())      {            static Uclock_T last;            while (1)            {                  if ((last.ticks > ptr->ticks) ||                        ((last.ticks == ptr->ticks) &&                        (last.count > ptr->count)))                  {                        ++(ptr->ticks);                        last.ticks = ptr->ticks;                        last.count = ptr->count;                        Uclock_(ptr);                  }                  else                  {                        last.ticks = ptr->ticks;                        last.count = ptr->count;                        break;                  }            }      }      return ((NULL == now) ? uclock_cnvrt(ptr) : -1.0);}/***  uclock_diff()****  Subtracts one Uclock_T value from another.****  Parameters: (All passed as pointers to Uclock_T structures)**              1 - First time (time to subtract)**              2 - Second time**              3 - Difference or NULL****  Returns : Difference converted to a uclock_t if parameter 3 is NULL, else**            returns -1.0 and difference is returned in structure pointed to**            by parameter 3.****  Note: uclock_diff() properly handles elapsed times spanning midnight,**        and is therefore preferable to simply subtracting uclock_t values.**        If you must subtract uclock_t values, convert negative results to**        positive by adding (UCLK_RLVR+1).*/uclock_t uclock_diff(Uclock_T *Start, Uclock_T *Stop, Uclock_T *Diff){      Uclock_T buf, *ptr = ((NULL == Diff) ? &buf : Diff);      /*      ** Add rollover constant if the day has changed      */      if (Start->ticks <= Stop->ticks)            ptr->ticks = Stop->ticks - Start->ticks;      else  ptr->ticks = Stop->ticks + 0x001800B0L - Start->ticks;      ptr->count = Stop->count - Start->count;      if (Stop->count < Start->count)            --(ptr->ticks);      return ((NULL == Diff) ? uclock_cnvrt(ptr) : -1.0);}/***  uclock_cnvrt()****  Converts from Uclock_T structure to a uclock_t value.****  Parameters: 1 - Pointer to Uclock_T structure to convert.****  Returns: uclock_t value.*/uclock_t uclock_cnvrt(Uclock_T *ticks){      return (uclock_t)(ticks->count) + (uclock_t)(65536.0 * ticks->ticks);}/***  usec_delay()****  Delays a specified number of microseconds.****  Parameters: 1 - Delay time in microseconds.****  Returns: Nothing****  Note: Uses integer math in a tight loop to maximize resolution.*/void usec_delay(unsigned long usecs){      Uclock_T tm0, tm1, diff;      unsigned long et;      assert(usecs < 40904449L);          /* Avoid 40.9 sec. overflow */      Uclock_(&tm0);      do      {            Uclock_(&tm1);            uclock_diff(&tm0, &tm1, &diff);            /*            ** Convert ticks to uSecs. using integer math            */            et = CAST(unsigned long, diff);            et *= 88L;            et /= 105L;      } while (usecs > et);}#ifdef TEST/***  Test main() adapted from Sample program #15 by K. Heidenstrom**  as cited above.*/#include <stdio.h>      /* Needed for printf()              */#include <stdlib.h>     /* Needed for exit()                */#include <conio.h>      /* Needed for kbhit() & getch()     */main(void){      Uclock_T ts, ts1, ts2;      unsigned int sched = 0;      unsigned int ch;      puts("Press any key to get timestamp; "            "press <Esc> for continuous test\n\n");      do      {            ch = getch();                             /* Get a keypress */            usec_clock(&ts);                          /* Get timestamp  */            printf("Absolute timestamp: 0x%08lX%04X units of 0.8381 us\n",                  ts.ticks, ts.count);            printf("...representing %f seconds since last midnight\n\n",                  uclock_cnvrt(&ts) / UCLK_TCK);      } while ((ch & 0xff) != '\x1b');      puts("\nProgram is now performing continuous timestamp test\n");      puts("Press <Esc> to exit\n");      ts1.ticks = ts.ticks;      ts1.count = ts.count;      while (1)      {            ts2.ticks = ts1.ticks;            ts2.count = ts1.count;            ts1.ticks = ts.ticks;            ts1.count = ts.count;            usec_clock(&ts);            printf("0x%08lX%04X\r",                  ts.ticks, ts.count);            if ((ts.ticks < ts1.ticks) || ((ts.ticks == ts1.ticks) &&                  (ts.count < ts1.count)))            /* Went backwards? */            {                  printf("Timestamp went backwards: 0x%08lX%04X, "                        "0x%08lX%04X, then 0x%08lX%04X\n",                        ts2.ticks, ts2.count,                        ts1.ticks, ts1.count,                        ts.ticks, ts.count);            }            ++sched;            if (!(sched & 0xff))            {                  if (kbhit())                  {                        if ('\x1b' == (getch() & 0xff))                              break;                  }            }      }      return EXIT_SUCCESS;}#endif /* TEST */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -