1. 问题分析

      移植glib中间件时,运行测试用例出现异常错误,定位问题为g_clock_gettime函数获取的时间和系统API获取的时间不一致导致。

      glib中间件中g_get_monotonic_time函数原型如程序清单 1.1所示。

程序清单1.1  g_clock_gettime函数原型

gint64  g_get_monotonic_time (void)
{
  struct timespec ts;
  gint result;

  result = clock_gettime (CLOCK_MONOTONIC, &ts);

  if G_UNLIKELY (result != 0)
     g_error ("GLib requires working CLOCK_MONOTONIC");

  return (((gint64) ts.tv_sec) * 1000000) + (ts.tv_nsec / 1000);
}

      经过分析,g_get_monotonic_time函数调用clock_gettime函数且传入的参数为CLOCK_MONOTONIC。

      SylixOS下在阻塞等待等操作获取时间时调用clock_gettime函数且传入的参数为CLOCK_REALTIME,所以导致glib中获取的时间和SylixOS获取的时间不一致,出现上述的问题。

2. 实现原理

      SylixOS下clock_getime函数实现如程序清单2.1所示。

程序清单  2.1  

__LW_RETU_FUNC_DEFINE(int, clock_gettime,
                      (clockid_t  clockid, struct timespec  *tv),
                      (clockid, tv))

      SylixOS下clock_gettime函数调用lib_clock_gettime函数,其函数原型为:

INT  lib_clock_gettime (clockid_t  clockid, struct timespec  *tv)

     函数lib_clock_gettime原型分析:

  • 函数执行成功返回ERROR_NONE,执行失败置错误码并返回PX_ERROR;

  •  参数clockid为获取时间模式;

  •  参数tv获取时间结构体;

     SylixOS提供四种获取时间模式,如表 2.1所示。

                                                                                 表2.1  获取时间模式

CLOCK_REALTIME

系统实时时间,随系统实时时间改变而改变,中间时刻如果系统时间被用户改动,则对应的时间相应改变

CLOCK_MONOTONIC

从系统启动开始计时,不受系统时间被用户改变的影响

CLOCK_PROCESS_CPUTIME_ID

系统CPU从本进程到当前代码花费的时间

CLOCK_THREAD_CPUTIME_ID

系统CPU从本线程到当前代码花费的时间

3. 测试用例

      测试程序代码如程序清单 3.1所示。

程序清单 3.1  获取时间示例

#include <stdio.h>
#include <time.h>

int  main (int  argc, char  **argv)
{
    struct timespec tv = {0, 0};

    clock_gettime(CLOCK_REALTIME, &tv);
    printf("CLOCK_REALTIME : %llu \n", tv.tv_sec * 1000 + tv.tv_nsec / 1000000);

    clock_gettime(CLOCK_MONOTONIC, &tv);
    printf("CLOCK_MONOTONIC : %llu \n", tv.tv_sec * 1000 + tv.tv_nsec / 1000000);

    clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &tv);
    printf("CLOCK_PROCESS_CPUTIME_ID : %llu \n", 
           tv.tv_sec * 1000 + tv.tv_nsec / 1000000);

    clock_gettime(CLOCK_THREAD_CPUTIME_ID, &tv);
    printf("CLOCK_THREAD_CPUTIME_ID : %llu \n", 
            tv.tv_sec * 1000 + tv.tv_nsec / 1000000);

    return  0;
}

      如程序清单 3.1所示,测试用例中通过clock_gettime函数分别获取四种模式下的时间,在模拟器上运行测试程序,运行结果如下:

[root@sylixos:/apps/test]# ./test
CLOCK_REALTIME : 946846519684
CLOCK_MONOTONIC : 161719686
CLOCK_PROCESS_CPUTIME_ID : 147
CLOCK_THREAD_CPUTIME_ID : 157