LCOV - code coverage report
Current view: directory - src/shared/platform/osx - nacl_clock.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 72 67 93.1 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright (c) 2012 The Native Client Authors. All rights reserved.
       3                 :  * Use of this source code is governed by a BSD-style license that can be
       4                 :  * found in the LICENSE file.
       5                 :  */
       6                 : 
       7                 : #include "native_client/src/shared/platform/nacl_clock.h"
       8                 : 
       9                 : #include "native_client/src/include/nacl_macros.h"
      10                 : #include "native_client/src/include/portability.h"
      11                 : #include "native_client/src/shared/platform/nacl_host_desc.h"
      12                 : #include "native_client/src/shared/platform/nacl_log.h"
      13                 : #include "native_client/src/shared/platform/nacl_time.h"
      14                 : #include "native_client/src/trusted/service_runtime/include/sys/errno.h"
      15                 : 
      16                 : /*
      17                 :  * OSX does not include POSIX.1-2011 functions, so we emulate using
      18                 :  * Mach calls.
      19                 :  */
      20                 : #include <mach/mach.h>
      21                 : #include <mach/mach_time.h>
      22                 : #include <mach/task.h>
      23                 : #include <mach/task_info.h>
      24                 : #include <mach/thread_info.h>
      25                 : #include <pthread.h>
      26                 : 
      27                 : static int                        g_NaClClock_is_initialized = 0;
      28                 : static mach_timebase_info_data_t  g_NaCl_time_base_info;
      29                 : 
      30                 : int NaClClockInit(void) {
      31             331 :   g_NaClClock_is_initialized = (mach_timebase_info(&g_NaCl_time_base_info)
      32                 :                                 == KERN_SUCCESS);
      33                 : 
      34             331 :   return g_NaClClock_is_initialized;
      35                 : }
      36                 : 
      37              53 : void NaClClockFini(void) {}
      38                 : 
      39               8 : int NaClClockGetRes(nacl_clockid_t            clk_id,
      40               8 :                     struct nacl_abi_timespec  *res) {
      41               8 :   int             rv = -NACL_ABI_EINVAL;
      42               8 :   uint64_t        t_resolution_ns;
      43               8 :   struct timespec host_res;
      44                 : 
      45               8 :   if (!g_NaClClock_is_initialized) {
      46               0 :     NaClLog(LOG_FATAL,
      47                 :             "NaClClockGetRes invoked without successful NaClClockInit\n");
      48               0 :   }
      49              16 :   switch (clk_id) {
      50                 :     case NACL_CLOCK_REALTIME:
      51               2 :       t_resolution_ns = NaClTimerResolutionNanoseconds();
      52               2 :       host_res.tv_sec = (time_t) (t_resolution_ns / NACL_NANOS_PER_UNIT);
      53               2 :       host_res.tv_nsec = (long)  (t_resolution_ns % NACL_NANOS_PER_UNIT);
      54               2 :       rv = 0;
      55               2 :       break;
      56                 :     case NACL_CLOCK_MONOTONIC:
      57               2 :       host_res.tv_sec = 0;
      58                 :       /* round up */
      59               2 :       host_res.tv_nsec = ((g_NaCl_time_base_info.numer
      60                 :                            + g_NaCl_time_base_info.denom - 1)
      61                 :                           / g_NaCl_time_base_info.denom);
      62               2 :       rv = 0;
      63               2 :       break;
      64                 :     case NACL_CLOCK_PROCESS_CPUTIME_ID:
      65                 :     case NACL_CLOCK_THREAD_CPUTIME_ID:
      66               4 :       host_res.tv_sec = 0;
      67               4 :       host_res.tv_nsec = 1;
      68               4 :       rv = 0;
      69               4 :       break;
      70                 :   }
      71               8 :   if (0 == rv) {
      72               8 :     res->tv_sec = host_res.tv_sec;
      73               8 :     res->tv_nsec = host_res.tv_nsec;
      74               8 :   }
      75               8 :   return rv;
      76                 : }
      77                 : 
      78         6337431 : int NaClClockGetTime(nacl_clockid_t            clk_id,
      79         6337431 :                      struct nacl_abi_timespec  *tp) {
      80         6337431 :   int                               rv = -NACL_ABI_EINVAL;
      81         6337431 :   struct nacl_abi_timeval           tv;
      82         6337431 :   uint64_t                          tick_cur;
      83         6337431 :   uint64_t                          tick_ns;
      84         6337431 :   struct task_absolutetime_info     absolutetime_info;
      85         6337431 :   thread_basic_info_data_t          _basic_info;
      86         6337431 :   thread_basic_info_t               basic_info = &_basic_info;
      87         6337431 :   mach_msg_type_number_t            count;
      88                 : 
      89         6337431 :   if (!g_NaClClock_is_initialized) {
      90               0 :     NaClLog(LOG_FATAL,
      91                 :             "NaClClockGetTime invoked without successful NaClClockInit\n");
      92               0 :   }
      93        12674862 :   switch (clk_id) {
      94                 :     case NACL_CLOCK_REALTIME:
      95               9 :       rv = NaClGetTimeOfDay(&tv);
      96               9 :       if (0 == rv) {
      97               9 :         tp->tv_sec = tv.nacl_abi_tv_sec;
      98               9 :         tp->tv_nsec = tv.nacl_abi_tv_usec * 1000;
      99               9 :       }
     100               9 :       break;
     101                 :     case NACL_CLOCK_MONOTONIC:
     102         6337396 :       tick_cur = mach_absolute_time();
     103                 :       /*
     104                 :        * mach_absolute_time() returns ticks since boot, with enough
     105                 :        * bits for several hundred years if the ticks occur at one per
     106                 :        * nanosecond.  numer/denom gives ns/tick, and the scaling
     107                 :        * arithmetic should not result in over/underflows.
     108                 :        */
     109         6337396 :       tick_ns = (tick_cur * g_NaCl_time_base_info.numer
     110                 :                  / g_NaCl_time_base_info.denom);
     111         6337396 :       tp->tv_sec =  tick_ns / 1000000000;
     112         6337396 :       tp->tv_nsec = tick_ns % 1000000000;
     113         6337396 :       rv = 0;
     114         6337396 :       break;
     115                 :     case NACL_CLOCK_PROCESS_CPUTIME_ID:
     116              13 :       count = TASK_ABSOLUTETIME_INFO_COUNT;
     117                 : 
     118              13 :       if (KERN_SUCCESS != task_info(mach_task_self(),
     119                 :                                     TASK_ABSOLUTETIME_INFO,
     120                 :                                     (task_info_t) &absolutetime_info,
     121                 :                                     &count)) {
     122               0 :         break;
     123                 :       }
     124              13 :       tp->tv_sec = ((absolutetime_info.total_user
     125                 :                      + absolutetime_info.total_system)
     126                 :                     / NACL_NANOS_PER_UNIT);
     127              13 :       tp->tv_nsec = ((absolutetime_info.total_user
     128                 :                       + absolutetime_info.total_system)
     129                 :                      % NACL_NANOS_PER_UNIT);
     130              13 :       rv = 0;
     131              13 :       break;
     132                 :     case NACL_CLOCK_THREAD_CPUTIME_ID:
     133              13 :       count = THREAD_BASIC_INFO_COUNT;
     134                 : 
     135                 :       /*
     136                 :        * Don't use mach_thread_self() because it requires a separate
     137                 :        * mach_port_deallocate() system call to release it. Instead, rely on
     138                 :        * pthread's cached copy of the port.
     139                 :        */
     140              13 :       if (KERN_SUCCESS == thread_info(pthread_mach_thread_np(pthread_self()),
     141                 :                                       THREAD_BASIC_INFO,
     142                 :                                       (thread_info_t) basic_info,
     143                 :                                       &count)) {
     144              13 :         tick_ns = ((basic_info->user_time.microseconds
     145                 :                     + basic_info->system_time.microseconds)
     146                 :                    * NACL_NANOS_PER_MICRO);
     147              13 :         tp->tv_sec = (basic_info->user_time.seconds
     148                 :                       + basic_info->system_time.seconds
     149                 :                       + (tick_ns / NACL_NANOS_PER_UNIT));
     150              13 :         tp->tv_nsec = tick_ns % NACL_NANOS_PER_UNIT;
     151              13 :         rv = 0;
     152              13 :       }
     153              13 :       break;
     154                 :   }
     155         6337431 :   return rv;
     156                 : }

Generated by: LCOV version 1.7