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

📄 rvtimestamp.c

📁 基于h323协议的软phone
💻 C
📖 第 1 页 / 共 2 页
字号:
}

/* Set up a background process to wait the proper amount of */
/* time then signal the interrupt process to do the work. It */
/* doesn't hurt performance and doesn't have a problem unless */
/* the system always runs at 100% (over a period of weeks). */
OS_PROCESS(RvTimeCheckWait)
{
    for(;;) {
        delay(RvWrapcheckMs);
        signal_fsem(RvWrapCheck);
    }
}
#endif

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_NUCLEUS)
/* Called by periodic timer */
static VOID RvTimeCheckWrap(UNSIGNED param)
{
    UNSIGNED cur_tick;
    INT old_level;

    /* Timer runs at lowest HISR level so make sure we don't switch */
    old_level = NU_Local_Control_Interrupts(NU_DISABLE_INTERRUPTS);
    cur_tick = NU_Retrieve_Clock();
    if(cur_tick < RvLastTick)
        RvWrapCount += 1;
    RvLastTick = cur_tick;
    NU_Local_Control_Interrupts(old_level);
}
#endif

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_USER_DEFINED)
/* Called for us by user timestamp driver when wrap occurs */
static void RvTimeCheckWrap(void)
{
    RvHiresCount += (RvInt64)RvUserTimestampPeriod();
}
#endif

/* Get a high resolution relative time stamp. This value will never */
/* go backwards. This value returned is in nanoseconds and will never wrap */
/* (at least for about 290 years). */
RVCOREAPI RvInt64 RVCALLCONV RvTimestampGet(void)
{
    RvInt64 result;
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_POSIX)
    struct timespec tp;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_LINUX)
    unsigned long eax,edx;
    RvInt64 tickcount;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_WIN32)
    LARGE_INTEGER PerformanceCount;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_TIMESTAMP)
    RvInt64 tickcount, lastcount_copy1, lastcount_copy2;
    ULONG laststamp_copy;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_NORMAL)
    long long tickcount;
    long wrapcount_copy;
    ULONG cur_tick, lasttick_copy1, lasttick_copy2;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_PSOS)
#if (RV_TOOL_TYPE == RV_TOOL_TYPE_CADUL) && (RV_OS_VERSION == RV_OS_PSOS_2_0)
    /* we detour the lack of 64 bit (long long) support in psos v2.0, by
       using the compiler (CADUL) ability to transfer all his 'long' types to 64 bit. */
    long tickcount;
    unsigned int tickshi, tickslo;
#else
    long long tickcount;
    unsigned long tickshi, tickslo;
#endif
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_OSE)
    long wrapcount_copy;
    long long tickcount;
    OSTICK micro, cur_tick, lasttick_copy1, lasttick_copy2;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_NUCLEUS)
    long long tickcount;
    long wrapcount_copy;
    UNSIGNED cur_tick, lasttick_copy1, lasttick_copy2;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_UNIXWARE) 
    struct timeval tv; /* timeval structure */
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_EMBLINUX) 
    struct timeval {
        long tv_sec; /* timeval structure */ /*h.e ??? */
        long tv_usec;
    };
    struct timeval tv;  

#endif

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_USER_DEFINED)
    RvInt64 tickcount, lastcount_copy1, lastcount_copy2, laststamp_copy;
#endif

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_SOLARIS)
    result = (RvInt64)gethrtime();
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_POSIX)
    clock_gettime(CLOCK_REALTIME, &tp);
    result = ((tp.tv_sec - RvStartingTime) * RV_TIME64_NSECPERSEC) + tp.tv_nsec;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_LINUX)
    rdtsc(eax,edx);
    tickcount = (RvInt64)edx * (RvInt64)ULONG_MAX + (RvInt64)edx + (RvInt64)eax;
    /* convert to nanosecs and maintain resolution, works up to about */
    /* a 9 gigaherz clock */
    result = (tickcount / RvTickHz) * RV_TIME64_NSECPERSEC;
    result += (((tickcount % RvTickHz) * RV_TIME64_NSECPERSEC) / RvTickHz);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_EMBLINUX)
    gettimeofday(&tv, NULL);
    result = ((RvInt64)tv.tv_sec * RV_TIME64_NSECPERSEC) + ((RvInt64)tv.tv_usec * RV_TIME64_NSECPERUSEC);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_WIN32)
    QueryPerformanceCounter(&PerformanceCount);
    /* convert to nanosecs and maintain resolution */
    result = (PerformanceCount.QuadPart / RvTickHz) * RV_TIME64_NSECPERSEC;
    result += (((PerformanceCount.QuadPart % RvTickHz) * RV_TIME64_NSECPERSEC) / RvTickHz);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_TIMESTAMP)
    /* Get hires count and timestamp without locking */
    do {
        lastcount_copy1 = RvHiresCount;
        laststamp_copy = sysTimestampLock();
        lastcount_copy2= RvHiresCount;
    } while(lastcount_copy1 != lastcount_copy2);
    tickcount = lastcount_copy1 + (RvInt64)laststamp_copy;
    result = (tickcount / RvTickHz) * RV_TIME64_NSECPERSEC;
    result += (((tickcount % RvTickHz) * RV_TIME64_NSECPERSEC) / RvTickHz);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_NORMAL)
    /* Clock tick is only 32 bits, check for wrap without locking */
    do {
        lasttick_copy1 = RvLastTick;
        wrapcount_copy = RvWrapCount;
        lasttick_copy2 = RvLastTick;
    } while (lasttick_copy1 != lasttick_copy2); /* max 2 loops */

    cur_tick = tickGet();
    if(cur_tick < lasttick_copy1)
        wrapcount_copy += 1;
    tickcount = (RvInt64)cur_tick + (RvInt64)wrapcount_copy * (RvInt64)WRAP_TICKS;
    result = (tickcount / RvTickHz) * RV_TIME64_NSECPERSEC;
    result += (((tickcount % RvTickHz) * RV_TIME64_NSECPERSEC) / RvTickHz);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_PSOS)
#if (RV_OS_VERSION == RV_OS_PSOS_2_0)
   ULONG date;
   ULONG time;
   ULONG ticks;
   ULONG day;
   ULONG month;
   ULONG cur_time;
   static ULONG start_time = 0l;

#define PSOS_CLOCKS_PER_SEC 1000
   /* tm_get() resolution:
      date Specifies the clock date. date is encoded as follows:
        Field           Bits
        Year, A.D.      31-16
        Month (1-12)    15-8
        Day (1-31)      7-0
      time Specifies the clock time. time is encoded as follows:
        Field           Bits
        Hour (0-23)     31-16
        Minute (0-59)   15-8
        Second (0-59)   7-0*/
   if (!tm_get(&date, &time, &ticks))
       return RvTimestampErrorCode(RV_ERROR_UNKNOWN);
   month= ((date>>8 )&0x000000FF);
   day  = ((date    )&0x000000FF);
   if (!month) month = 1;
   if (!day) day = 1;
   if (!start_time)
       start_time = Rv64Multiply(((time >> 16)&0x0000FFFF),3600) + Rv64Multiply(((time>>8)&0x000000FF),60) + (time&0x000000FF);
   cur_time = Rv64Multiply(((time >> 16)&0x0000FFFF),3600) + Rv64Multiply(((time>>8)&0x000000FF),60) + (time&0x000000FF)+Rv64Multiply((day-1),86400) + Rv64Multiply((month-1),2678400);
   tickcount = Rv64Multiply(Rv64Divide(ticks, PSOS_CLOCKS_PER_SEC), RV_TIME64_NSECPERSEC) + 
               Rv64Divide(Rv64Multiply(Rv64Modulu(ticks, PSOS_CLOCKS_PER_SEC), RV_TIME64_NSECPERSEC), PSOS_CLOCKS_PER_SEC);
   result =  Rv64Multiply((cur_time - start_time), RV_TIME64_NSECPERSEC) + tickcount;
#else
    tm_getticks(&tickshi, &tickslo);
    tickcount = Rv64Multiply((RvInt64)tickshi, RV_INT64_MAX) + (RvInt64)tickshi + (RvInt64)tickslo;
    result = Rv64Multiply(Rv64Divide(tickcount, RvTickHz), RV_TIME64_NSECPERSEC);
    result += Rv64Divide(Rv64Multiply(Rv64Modulu(tickcount, RvTickHz), RV_TIME64_NSECPERSEC), RvTickHz);
#endif
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_OSE)
    /* Clock tick is only 32 bits, check for wrap without locking */
    do {
        lasttick_copy1 = RvLastTick;
        wrapcount_copy = RvWrapCount;
        lasttick_copy2 = RvLastTick;
    } while (lasttick_copy1 != lasttick_copy2); /* max 2 loops */

    cur_tick = get_systime(&micro);
    if(cur_tick < lasttick_copy1)
        wrapcount_copy += 1;
    tickcount = (RvInt64)cur_tick + (RvInt64)wrapcount_copy * (RvInt64)WRAP_TICKS;
    result = tickcount * RvTickPeriod + ((RvInt64)micro * RvInt64Const(1000));
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_NUCLEUS)
    /* Clock tick is only 32 bits, check for wrap without locking */
    do {
        lasttick_copy1 = RvLastTick;
        wrapcount_copy = RvWrapCount;
        lasttick_copy2 = RvLastTick;
    } while (lasttick_copy1 != lasttick_copy2); /* max 2 loops */

    cur_tick = NU_Retrieve_Clock();
    if(cur_tick < lasttick_copy1)
        wrapcount_copy += 1;
    tickcount = (RvInt64)cur_tick + (RvInt64)wrapcount_copy * (RvInt64)WRAP_TICKS;
    result = (tickcount / RvTickHz) * RV_TIME64_NSECPERSEC;
    result += (((tickcount % RvTickHz) * RV_TIME64_NSECPERSEC) / RvTickHz);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_UNIXWARE)
    /* We don't use a good clock on UnixWare since we can't find it... */
    gettimeofday(&tv, NULL);

    result = ((RvInt64)tv.tv_sec * RV_TIME64_NSECPERSEC) + ((RvInt64)tv.tv_usec * RV_TIME64_NSECPERUSEC);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_USER_DEFINED)
    /* Get hires count and timestamp without using a lock */
    do {
        lastcount_copy1 = RvHiresCount;
        laststamp_copy = (RvInt64)RvUserTimestampGet();
        lastcount_copy2= RvHiresCount;
    } while(lastcount_copy1 != lastcount_copy2);
    tickcount = lastcount_copy1 + laststamp_copy;
    result = (tickcount / RvTickHz) * RV_TIME64_NSECPERSEC;
    result += (((tickcount % RvTickHz) * RV_TIME64_NSECPERSEC) / RvTickHz);
#endif
    return result;
}

/* Returns resolution of high resolution in nanoseconds. */
RvInt64 RvTimestampResolution(void)
{
    RvInt64 result;
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_SOLARIS) || (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_POSIX)
    RvTime t;
#endif

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_POSIX)
    clock_getres(CLOCK_REALTIME, (struct timespec *)&t);
    result = RvTimeConvertTo64(&t);
#endif

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_SOLARIS)
#if defined(CLOCK_HIGHRES) /* If CLOCK_HIGHRES isn't defined, then it is pre Solaris 8 */
    clock_getres(CLOCK_HIGHRES, (struct timespec *)&t);
#else
    /* Solaris 2.6 and 7 don't have a way to find the resolution of the
     * hires timer. The wall clock resolution will be no worse, so its
     * the best we can do. */
    clock_getres(CLOCK_REALTIME, (struct timespec *)&t);
#endif
    result = RvTimeConvertTo64(&t);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_LINUX) || (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_NORMAL) || \
    (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_TIMESTAMP) || (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_PSOS) || \
    (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_NUCLEUS) || (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_WIN32) || \
    (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_USER_DEFINED)
    if(RvTickHz > RvInt64Const(1))
    {
        result = Rv64Divide(RV_TIME64_NSECPERSEC, RvTickHz);
    }
    else
        result = RV_TIME64_NSECPERSEC;
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_OSE)
    /* OSE never tells us the sub-tick resolution so return ticks */
    result = RvTickPeriod;
#endif

    return result;
}

#if defined(RV_TEST_CODE)
#include "rv64ascii.h"
#include "rvstdio.h"

void RvTimestampTest(void)
{
    RvStatus result;
    RvChar buf[RV_64TOASCII_BUFSIZE], inputbuf[81];
    RvInt64 res64;
    RvInt64 stamp;

    RvPrintf("Starting test of rvtimestamp.\n");

    /* Initialize needed modules */
    Rv64AsciiInit();

    result = RvTimestampInit();
    if(result == RV_OK) {
        RvPrintf("RvTimestampInit successful.\n");
    } else RvPrintf("RvTimestampInit failed. Error = %d\n", result);

    RvPrintf("Saved information:\n");
#if (RV_TIMESTAMP_TYPE != RV_TIMESTAMP_OSE) && (RV_TIMESTAMP_TYPE != RV_TIMESTAMP_SOLARIS) && \
    (RV_TIMESTAMP_TYPE != RV_TIMESTAMP_POSIX) && (RV_TIMESTAMP_TYPE != RV_TIMESTAMP_UNIXWARE) && \
    (RV_TIMESTAMP_TYPE != RV_TIMESTAMP_EMBLINUX) 
    Rv64toA(buf, RvTickHz);
    RvPrintf("  RvTickHz = %s\n", buf);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_NORMAL) ||  (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_OSE) || \
    (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_NUCLEUS)
    RvPrintf("  RvWrapCount = %d\n", RvWrapCount);
    RvPrintf("  RvLastTick = %lu\n", RvLastTick);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_TIMESTAMP)
    Rv64UtoA(buf, RvHiresCount);
    RvPrintf("  RvHiresCount = %s\n", buf);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_OSE)
    Rv64toA(buf, RvTickPeriod);
    RvPrintf("  RvTickPeriod = %s\n", buf);
    RvPrintf("  RvWrapcheckMs = %d\n", RvWrapcheckMs);
#endif

    res64 = RvTimestampResolution();
    Rv64toA(buf, res64);
    RvPrintf("RvTimestampResolution = %s\n", buf);

    stamp = RvTimestampGet();
    Rv64toA(buf, stamp);
    RvPrintf("RvTimestampGet = %s\n", buf);

    /* Let user wait for some time to pass */
    RvPrintf("\nWait a few seconds and then press ENTER (optionally change system clock): ");
    fflush(stdout);
    fflush(stdin);
    fgets(inputbuf, sizeof(inputbuf), stdin);
    RvPrintf("\n");

    stamp = RvTimestampGet();
    Rv64toA(buf, stamp);
    RvPrintf("RvTimestampGet = %s\n", buf);

#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_NORMAL) ||  (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_OSE) || \
(RV_TIMESTAMP_TYPE == RV_TIMESTAMP_NUCLEUS)
    RvPrintf("  RvWrapCount = %d\n", RvWrapCount);
    RvPrintf("  RvLastTick = %lu\n", RvLastTick);
#endif
#if (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_VXWORKS_TIMESTAMP) || (RV_TIMESTAMP_TYPE == RV_TIMESTAMP_USER_DEFINED)
    Rv64UtoA(buf, RvHiresCount);
    RvPrintf("  RvHiresCount = %s\n", buf);
#endif

    result = RvTimestampEnd();
    if(result == RV_OK) {
        RvPrintf("RvTimestampEnd successful.\n");
    } else RvPrintf("RvTimestampEnd failed. Error = %d\n", result);

    Rv64AsciiEnd();
}
#endif /* RV_TEST_CODE */

⌨️ 快捷键说明

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