LCOV - code coverage report
Current view: top level - aws-c-common/source/posix - clock.c (source / functions) Hit Total Coverage
Test: all_fuzz.info Lines: 0 32 0.0 %
Date: 2021-04-23 16:28:21 Functions: 0 2 0.0 %

          Line data    Source code
       1             : /**
       2             :  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
       3             :  * SPDX-License-Identifier: Apache-2.0.
       4             :  */
       5             : 
       6             : #include <aws/common/clock.h>
       7             : 
       8             : #include <time.h>
       9             : 
      10             : static const uint64_t NS_PER_SEC = 1000000000;
      11             : 
      12             : #if defined(CLOCK_MONOTONIC_RAW)
      13           0 : #    define HIGH_RES_CLOCK CLOCK_MONOTONIC_RAW
      14             : #else
      15             : #    define HIGH_RES_CLOCK CLOCK_MONOTONIC
      16             : #endif
      17             : 
      18             : /* This entire compilation branch has two goals. First, prior to OSX Sierra, clock_gettime does not exist on OSX, so we
      19             :  * already need to branch on that. Second, even if we compile on a newer OSX, which we will always do for bindings (e.g.
      20             :  * python, dotnet, java etc...), we have to worry about the same lib being loaded on an older version, and thus, we'd
      21             :  * get linker errors at runtime. To avoid this, we do a dynamic load
      22             :  * to keep the function out of linker tables and only use the symbol if the current running process has access to the
      23             :  * function. */
      24             : #if defined(__MACH__)
      25             : #    include <AvailabilityMacros.h>
      26             : #    include <aws/common/thread.h>
      27             : #    include <dlfcn.h>
      28             : #    include <sys/time.h>
      29             : 
      30             : static int s_legacy_get_time(uint64_t *timestamp) {
      31             :     struct timeval tv;
      32             :     int ret_val = gettimeofday(&tv, NULL);
      33             : 
      34             :     if (ret_val) {
      35             :         return aws_raise_error(AWS_ERROR_CLOCK_FAILURE);
      36             :     }
      37             : 
      38             :     uint64_t secs = (uint64_t)tv.tv_sec;
      39             :     uint64_t u_secs = (uint64_t)tv.tv_usec;
      40             :     *timestamp = (secs * NS_PER_SEC) + (u_secs * 1000);
      41             :     return AWS_OP_SUCCESS;
      42             : }
      43             : 
      44             : #    if MAC_OS_X_VERSION_MAX_ALLOWED >= 101200
      45             : static aws_thread_once s_thread_once_flag = AWS_THREAD_ONCE_STATIC_INIT;
      46             : static int (*s_gettime_fn)(clockid_t __clock_id, struct timespec *__tp) = NULL;
      47             : 
      48             : static void s_do_osx_loads(void *user_data) {
      49             :     (void)user_data;
      50             :     s_gettime_fn = (int (*)(clockid_t __clock_id, struct timespec * __tp)) dlsym(RTLD_DEFAULT, "clock_gettime");
      51             : }
      52             : 
      53             : int aws_high_res_clock_get_ticks(uint64_t *timestamp) {
      54             :     aws_thread_call_once(&s_thread_once_flag, s_do_osx_loads, NULL);
      55             :     int ret_val = 0;
      56             : 
      57             :     if (s_gettime_fn) {
      58             :         struct timespec ts;
      59             :         ret_val = s_gettime_fn(HIGH_RES_CLOCK, &ts);
      60             : 
      61             :         if (ret_val) {
      62             :             return aws_raise_error(AWS_ERROR_CLOCK_FAILURE);
      63             :         }
      64             : 
      65             :         uint64_t secs = (uint64_t)ts.tv_sec;
      66             :         uint64_t n_secs = (uint64_t)ts.tv_nsec;
      67             :         *timestamp = (secs * NS_PER_SEC) + n_secs;
      68             :         return AWS_OP_SUCCESS;
      69             :     }
      70             : 
      71             :     return s_legacy_get_time(timestamp);
      72             : }
      73             : 
      74             : int aws_sys_clock_get_ticks(uint64_t *timestamp) {
      75             :     aws_thread_call_once(&s_thread_once_flag, s_do_osx_loads, NULL);
      76             :     int ret_val = 0;
      77             : 
      78             :     if (s_gettime_fn) {
      79             :         struct timespec ts;
      80             :         ret_val = s_gettime_fn(CLOCK_REALTIME, &ts);
      81             :         if (ret_val) {
      82             :             return aws_raise_error(AWS_ERROR_CLOCK_FAILURE);
      83             :         }
      84             : 
      85             :         uint64_t secs = (uint64_t)ts.tv_sec;
      86             :         uint64_t n_secs = (uint64_t)ts.tv_nsec;
      87             :         *timestamp = (secs * NS_PER_SEC) + n_secs;
      88             :         return AWS_OP_SUCCESS;
      89             :     }
      90             :     return s_legacy_get_time(timestamp);
      91             : }
      92             : #    else
      93             : int aws_high_res_clock_get_ticks(uint64_t *timestamp) {
      94             :     return s_legacy_get_time(timestamp);
      95             : }
      96             : 
      97             : int aws_sys_clock_get_ticks(uint64_t *timestamp) {
      98             :     return s_legacy_get_time(timestamp);
      99             : }
     100             : 
     101             : #    endif /* MAC_OS_X_VERSION_MAX_ALLOWED >= 101200 */
     102             : /* Everywhere else, just link clock_gettime in directly */
     103             : #else
     104           0 : int aws_high_res_clock_get_ticks(uint64_t *timestamp) {
     105           0 :     int ret_val = 0;
     106           0 : 
     107           0 :     struct timespec ts;
     108           0 : 
     109           0 :     ret_val = clock_gettime(HIGH_RES_CLOCK, &ts);
     110           0 : 
     111           0 :     if (ret_val) {
     112           0 :         return aws_raise_error(AWS_ERROR_CLOCK_FAILURE);
     113           0 :     }
     114           0 : 
     115           0 :     uint64_t secs = (uint64_t)ts.tv_sec;
     116           0 :     uint64_t n_secs = (uint64_t)ts.tv_nsec;
     117           0 :     *timestamp = (secs * NS_PER_SEC) + n_secs;
     118           0 :     return AWS_OP_SUCCESS;
     119           0 : }
     120             : 
     121           0 : int aws_sys_clock_get_ticks(uint64_t *timestamp) {
     122           0 :     int ret_val = 0;
     123           0 : 
     124           0 :     struct timespec ts;
     125           0 :     ret_val = clock_gettime(CLOCK_REALTIME, &ts);
     126           0 :     if (ret_val) {
     127           0 :         return aws_raise_error(AWS_ERROR_CLOCK_FAILURE);
     128           0 :     }
     129           0 : 
     130           0 :     uint64_t secs = (uint64_t)ts.tv_sec;
     131           0 :     uint64_t n_secs = (uint64_t)ts.tv_nsec;
     132           0 :     *timestamp = (secs * NS_PER_SEC) + n_secs;
     133           0 : 
     134           0 :     return AWS_OP_SUCCESS;
     135           0 : }
     136             : #endif /* defined(__MACH__) */

Generated by: LCOV version 1.13