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

📄 rvclock.c

📁 基于h323协议的软phone
💻 C
字号:
/***********************************************************************
Filename   : rvclock.c
Description: clock functions for getting wall time
************************************************************************
        Copyright (c) 2001 RADVISION Inc. and RADVISION Ltd.
************************************************************************
NOTICE:
This document contains information that is confidential and proprietary
to RADVISION Inc. and RADVISION Ltd.. No part of this document may be
reproduced in any form whatsoever without written prior approval by
RADVISION Inc. or RADVISION Ltd..

RADVISION Inc. and RADVISION Ltd. reserve the right to revise this
publication and make changes without obligation to notify any person of
such revisions or changes.
***********************************************************************/
#include "rvclock.h"
#include "rvtm.h"

/* Required OS Specific headers files */
#if (RV_CLOCK_TYPE == RV_CLOCK_LINUX) || (RV_CLOCK_TYPE == RV_CLOCK_UNIXWARE)
#include <sys/time.h>
#include <unistd.h>

#elif (RV_CLOCK_TYPE == RV_CLOCK_WIN32)
#include <windows.h>

#elif (RV_CLOCK_TYPE == RV_CLOCK_VXWORKS)
#include <vxworks.h>
#include <timers.h>

#elif (RV_CLOCK_TYPE == RV_CLOCK_PSOS)
#include <psos.h>
#if (RV_OS_VERSION == RV_OS_PSOS_2_0)
#include <psoscfg.h>
#endif
extern pSOS_CT PsosCfg;   /* pSOS config table declared by pRISM+ */

#elif (RV_CLOCK_TYPE == RV_CLOCK_OSE)
#include <ose.h>
#if (RV_OS_VERSION > RV_OS_OSE_4_2)
#include <rtc.h>
#endif

#elif (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
#include <nucleus.h>
#include <target.h>
#endif

/* OS specific declarations and variables */
#if (RV_CLOCK_TYPE == RV_CLOCK_WIN32)
/* Windows epoc is Jan 1, 1601, not Jan 1 1970 (100ns increments)*/
#define EPOCHDELTA RvUint64Const(116444736000000000)

#elif (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
static RvInt32 timezero;            /* # of seconds since 1970 equating to 0 ticks */
#endif

/* Lets make error codes a little easier to type */
#define RvClockErrorCode(_e) RvErrorCode(RV_ERROR_LIBCODE_CCORE, RV_CCORE_MODULE_CLOCK, (_e))

RvStatus RvClockInit(void)
{
#if (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
    timezero = RvInt32Const(0); /* We need to track our own wall time */
#endif
    return RV_OK;
}

RvStatus RvClockEnd(void)
{
    return RV_OK;
}

/* Get time since epoch -- can vary due to system time adjustments */
/* returns time in seconds and fills result with seconds and nanoseconds */
/* if result is not NULL. Epoch is January 1, 1970 */
RVCOREAPI RvInt32 RVCALLCONV RvClockGet(RvTime *t)
{
    RvTime temptime, *result;
#if (RV_CLOCK_TYPE == RV_CLOCK_LINUX) || (RV_CLOCK_TYPE == RV_CLOCK_UNIXWARE)
    struct timeval tv;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_WIN32)
    SYSTEMTIME systime;
    FILETIME filetime;
    ULARGE_INTEGER *uint_time;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_PSOS)
    RvInt64 divRes;
    RvTm tm;
    unsigned long datefield, timefield, ticks;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_OSE)
#if (RV_OS_VERSION > RV_OS_OSE_4_2)
    struct timeval tv;
#else
    struct TimePair tvp;
#endif
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
    UNSIGNED curticks;
#endif

    if(t == NULL) {  /* use temptime if user doesn't provide result struct */
        result = &temptime;
    } else result = t;

#if (RV_CLOCK_TYPE == RV_CLOCK_SOLARIS) || (RV_CLOCK_TYPE == RV_CLOCK_VXWORKS) || \
    (RV_CLOCK_TYPE == RV_CLOCK_TRU64)
    clock_gettime(CLOCK_REALTIME, (struct timespec *)result);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_LINUX)
    gettimeofday(&tv, NULL);
    TIMEVAL_TO_TIMESPEC(&tv, (struct timespec *)result);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_UNIXWARE)
    gettimeofday(&tv, NULL);
    result->sec = tv.tv_sec;
    result->nsec = tv.tv_usec * 1000;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_WIN32)
    GetSystemTime(&systime);
    SystemTimeToFileTime(&systime, &filetime);
    uint_time = (ULARGE_INTEGER *)&filetime;
    uint_time->QuadPart = uint_time->QuadPart - EPOCHDELTA;
    RvTimeSetSecs(result, (RvInt32)(uint_time->QuadPart / 10000000Ui64));
    RvTimeSetNsecs(result, (RvInt32)((uint_time->QuadPart % 10000000Ui64) * 100Ui64));
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_PSOS)
    tm_get(&datefield, &timefield, &ticks);
    RvTmSetSec(&tm, (RvInt)(timefield & 0xFFUL));
    RvTmSetMin(&tm, (RvInt)((timefield >> 8) & 0xFFUL));
    RvTmSetHour(&tm, (RvInt)((timefield >> 16) & 0xFFFFUL));
    RvTmSetMday(&tm, (RvInt)(datefield & 0xFFUL));
    RvTmSetMon(&tm, (RvInt)((datefield >> 8) & 0xFFUL));
    RvTmSetYear(&tm, (RvInt)((datefield >> 16) & 0xFFFFUL));
    RvTmSetIsdst(&tm, RvIntConst(-1));
    divRes = Rv64Divide((RvInt64)RV_TIME_NSECPERSEC, (RvInt64)PsosCfg.kc_ticks2sec);
    RvTmSetNsec(&tm, (RvInt32)( Rv64Multiply((RvInt64)ticks, divRes) ));
    RvTmConvertToTime(&tm, result);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_OSE)
#if (RV_OS_VERSION > RV_OS_OSE_4_2)
    gettimeofday(&tv, NULL);
    RvTimeSetSecs(result, (RvInt32)tv.tv_sec);
    RvTimeSetNsecs(result, (RvInt32)(tv.tv_usec * 1000UL));
#else
    /* Use older interface */
    get_time(&tvp);
    RvTimeSetSecs(result, (RvInt32)tvp.seconds);
    RvTimeSetNsecs(result, (RvInt32)(tvp.micros * 1000UL));
#endif
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
    /* Nucleus doesn't have a wall clock so we have to keep one */
    curticks = NU_Retrieve_Clock();
    RvTimeSetSecs(result, (RvInt32)(curticks / TICKS_PER_SECOND) + timezero);
    RvTimeSetNsecs(result, (RvInt32)(((RvInt64)(curticks % TICKS_PER_SECOND) * RV_TIME64_NSECPERSEC) / (RvInt64)TICKS_PER_SECOND));
#endif
    return RvTimeGetSecs(result);
}

/* Returns resolution of wall time in nanoseconds. Returns seconds */
/* nanoseconds in result structure although I don't believe it will */
/* ever be worse than 1 second. This a nanoseconds value of 0 probably */
/* means the value is 1 second. */
RvInt32 RvClockResolution(RvTime *t)
{
    RvTime temptime, *result;
#if (RV_CLOCK_TYPE == RV_CLOCK_OSE)
    OSTIME systick;
#endif

    if(t == NULL) {  /* use temptime if user doesn't provide result struct */
        result = &temptime;
    } else result = t;

#if (RV_CLOCK_TYPE == RV_CLOCK_SOLARIS) ||  (RV_CLOCK_TYPE == RV_CLOCK_VXWORKS) || \
    (RV_CLOCK_TYPE == RV_CLOCK_TRU64)
    clock_getres(CLOCK_REALTIME, (struct timespec *)result);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_LINUX) ||  (RV_CLOCK_TYPE == RV_CLOCK_WIN32) || \
    (RV_CLOCK_TYPE == RV_CLOCK_UNIXWARE)
    RvTimeSetSecs(result, RvInt32Const(0));
    RvTimeSetNsecs(result, (RvInt32)(RV_TIME_NSECPERSEC / CLOCKS_PER_SEC));
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_PSOS)
    RvTimeSetSecs(result, RvInt32Const(0));
    RvTimeSetNsecs(result, (RvInt32)Rv64Divide((unsigned long)RV_TIME_NSECPERSEC, PsosCfg.kc_ticks2sec));
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
    RvTimeSetSecs(result, RvInt32Const(0));
    RvTimeSetNsecs(result, (RvInt32)(RV_TIME_NSECPERSEC / TICKS_PER_SECOND));
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_OSE)
    systick = system_tick();
    RvTimeSetSecs(result, (RvInt32)((RvInt64)systick * RvInt64Const(1000) / (RvInt64)RV_TIME_NSECPERSEC));
    RvTimeSetNsecs(result, (RvInt32)(((RvInt64)systick * RvInt64Const(1000)) % (RvInt64)RV_TIME_NSECPERSEC));
#endif

    return RvTimeGetNsecs(result);
}

/* Set time since epoch (January 1, 1970) -- on most systems just */
/* makes call to OS. On those systems with no wall clock, calculate */
/* wall time based on clock tick. Returns RV_OK if clock it set */
/* properly. Remember that certain systems require special privileges */
/* to change the system clock. */
RvStatus RvClockSet(const RvTime *t)
{
    RvStatus result;
#if (RV_CLOCK_TYPE == RV_CLOCK_LINUX) || (RV_CLOCK_TYPE == RV_CLOCK_UNIXWARE)
    struct timeval tv;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_WIN32)
    SYSTEMTIME systime;
    FILETIME filetime;
    ULARGE_INTEGER *uint_time;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_PSOS)
    RvTm tm;
    unsigned long datefield, timefield, ticks;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_OSE)
    struct TimePair tvp;
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
    UNSIGNED curticks;
    RvInt32 cursecs;
#endif

#if defined(RV_NULLCHECK)
    if(t == NULL) return RvClockErrorCode(RV_ERROR_NULLPTR);
#endif
    result = RV_OK;

#if (RV_CLOCK_TYPE == RV_CLOCK_SOLARIS) ||  (RV_CLOCK_TYPE == RV_CLOCK_VXWORKS) || \
    (RV_CLOCK_TYPE == RV_CLOCK_TRU64)
    if(clock_settime(CLOCK_REALTIME, (struct timespec *)t) != 0)

#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_LINUX)
    TIMESPEC_TO_TIMEVAL(&tv, (struct timespec *)t);
    if(settimeofday(&tv, NULL)!= 0)
        result = RvClockErrorCode(RV_ERROR_UNKNOWN);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_UNIXWARE)
    tv.tv_sec = t->sec;
    tv.tv_usec = t->nsec / 1000;
    if(settimeofday(&tv, NULL)!= 0)
        result = RvClockErrorCode(RV_ERROR_UNKNOWN);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_WIN32)
    uint_time = (ULARGE_INTEGER *)&filetime;
    uint_time->QuadPart = (ULONGLONG)RvTimeGetSecs(t) * 10000000Ui64 +
                          (ULONGLONG)RvTimeGetNsecs(t) / 100Ui64 + EPOCHDELTA;
    if((FileTimeToSystemTime(&filetime, &systime) == 0) || (SetSystemTime(&systime) == 0))
        result = RvClockErrorCode(RV_ERROR_UNKNOWN);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_PSOS)
    if(RvTmConstructUtc(&tm, t) != RV_OK)
        return RvClockErrorCode(RV_ERROR_UNKNOWN);

    ticks = (unsigned long)(Rv64Divide(Rv64Multiply((RvInt64)RvTmGetNsec(t), 
                                                    (RvInt64)PsosCfg.kc_ticks2sec),
                                       (RvInt64)RV_TIME_NSECPERSEC));
    timefield = ((unsigned long)RvTmGetHour(&tm) << 16) |
                ((unsigned long)RvTmGetMin(&tm) << 8) |
                (unsigned long)RvTmGetSec(&tm);
    datefield = ((unsigned long)RvTmGetYear(&tm) << 16) |
                ((unsigned long)RvTmGetMon(&tm) << 8) |
                (unsigned long)RvTmGetMday(&tm);
    if(tm_set(datefield, timefield, ticks) != 0)
        result = RvClockErrorCode(RV_ERROR_UNKNOWN);
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_OSE)
    tvp.seconds = (unsigned long)RvTimeGetSecs(t);
    tvp.micros = (unsigned long)RvTimeGetNsecs(t) / 1000UL;
#if (RV_OS_VERSION > RV_OS_OSE_4_2)
    /* Use new function name but we really need settimeofday so it */
    /* goes with gettimeofday. */
    rtc_set_time(&tvp);
#else
    /* Use old interface */
    set_time(&tvp);
#endif
#endif
#if (RV_CLOCK_TYPE == RV_CLOCK_NUCLEUS)
    /* Nucleus doesn't have a wall clock so we have to keep one. */
    /* Only set seconds so we don't have to do locking. */
    curticks = NU_Retrieve_Clock();
    cursecs = (RvInt32)(curticks / TICKS_PER_SECOND);
    cursecs = RvTimeGetSecs(t) - cursecs;
    if(cursecs < 0)
        result = RvClockErrorCode(RV_ERROR_UNKNOWN);
    timezero = cursecs;
#endif

    return result;
}

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

#define TESTTIME_SEC 997380342  /* seconds since 1970 */
#define TESTTIME_NSEC 750000000 /* in nanoseconds */

void RvClockTest(void)
{
    RvStatus result;
    RvTime t1, t2, t3, tres;
    RvInt32 secs, nsecs;

    RvPrintf("Starting test of rvclock.\n");
    result = RvClockInit();
    if(result == RV_OK) {
        RvPrintf("RvClockInit successful.\n");
    } else RvPrintf("RvClockInit failed. Error = %d\n", result);

    secs = RvClockGet(&t1);
    RvPrintf("RvClockGet: Retuned Secs = %d, Time = %d %d\n", secs, RvTimeGetSecs(&t1), RvTimeGetNsecs(&t1));

    nsecs = RvClockResolution(&tres);
    RvPrintf("RvClockResolution: Retuned Nsecs = %d, Time = %d %d\n", nsecs, RvTimeGetSecs(&tres), RvTimeGetNsecs(&tres));

    result = RvClockSet(NULL);
    RvPrintf("RvClockSet(NULL): result = %d, Lib:%d Module:%d Error:%d\n", result, RvErrorGetLib(result), RvErrorGetModule(result), RvErrorGetCode(result));

    RvTimeConstruct(&t2, TESTTIME_SEC, TESTTIME_NSEC);
    RvPrintf("RvClockSet(%d, %d): ", TESTTIME_SEC, TESTTIME_NSEC);
    result = RvClockSet(&t2);
    if(result == RV_OK) {
        RvPrintf("OK\n");
        secs = RvClockGet(&t3);
        RvPrintf("RvClockGet: Return = %d, Time = %d %d\n", secs, RvTimeGetSecs(&t3), RvTimeGetNsecs(&t3));

        /* set the time back to what we start with so we don't mess the */
        /* clockup too much. */
        RvPrintf("RvClockSet(%d, %d): ", RvTimeGetSecs(&t1), RvTimeGetNsecs(&t1));
        result = RvClockSet(&t1);
        if(result == RV_OK) {
            RvPrintf("OK\n");
        } else RvPrintf("ERROR! Code: %d\n", result);

    } else RvPrintf("ERROR! Code: %d\n", result);

    result = RvClockEnd();
    if(result == RV_OK) {
        RvPrintf("RvClockEnd successful.\n");
    } else RvPrintf("RvClockEnd failed. Error = %d\n", result);
}
#endif /* RV_TEST_CODE */

⌨️ 快捷键说明

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