SylixOS下移植glib時clock_gettime函數分析

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


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章