root/opal/mca/timer/darwin/timer_darwin_component.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. opal_timer_darwin_open

   1 /* -*- Mode: C; c-basic-offset:4 ; indent-tabs-mode:nil -*- */
   2 /*
   3  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
   4  *                         University Research and Technology
   5  *                         Corporation.  All rights reserved.
   6  * Copyright (c) 2004-2014 The University of Tennessee and The University
   7  *                         of Tennessee Research Foundation.  All rights
   8  *                         reserved.
   9  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
  10  *                         University of Stuttgart.  All rights reserved.
  11  * Copyright (c) 2004-2005 The Regents of the University of California.
  12  *                         All rights reserved.
  13  * Copyright (c) 2007-2015 Los Alamos National Security, LLC.  All rights
  14  *                         reserved.
  15  * $COPYRIGHT$
  16  *
  17  * Additional copyrights may follow
  18  *
  19  * $HEADER$
  20  */
  21 
  22 #include "opal_config.h"
  23 
  24 #include "opal/mca/timer/timer.h"
  25 #include "opal/mca/timer/darwin/timer_darwin.h"
  26 #include "opal/constants.h"
  27 
  28 opal_timer_t opal_timer_darwin_freq = {0};
  29 mach_timebase_info_data_t opal_timer_darwin_info = {.denom = 0};
  30 opal_timer_t opal_timer_darwin_bias = {0};
  31 
  32 static int opal_timer_darwin_open(void);
  33 
  34 const opal_timer_base_component_2_0_0_t mca_timer_darwin_component = {
  35     /* First, the mca_component_t struct containing meta information
  36        about the component itself */
  37     .timerc_version = {
  38         OPAL_TIMER_BASE_VERSION_2_0_0,
  39 
  40         /* Component name and version */
  41         .mca_component_name = "darwin",
  42         MCA_BASE_MAKE_VERSION(component, OPAL_MAJOR_VERSION, OPAL_MINOR_VERSION,
  43                               OPAL_RELEASE_VERSION),
  44 
  45         .mca_open_component = opal_timer_darwin_open,
  46     },
  47     .timerc_data = {
  48         /* The component is checkpoint ready */
  49         MCA_BASE_METADATA_PARAM_CHECKPOINT
  50     },
  51 };
  52 
  53 /* mach_timebase_info() returns a fraction that can be multiplied
  54    by the difference between two calls to mach_absolute_time() to
  55    get the number of nanoseconds that passed between the two
  56    calls.
  57 
  58    On PPC, mach_timebase_info returns numer = 1000000000 and denom
  59    = 33333335 (or possibly 25000000, depending on the machine).
  60    mach_absolute_time() returns a cycle count from the global
  61    clock, which runs at 25 - 33MHz, so dividing the cycle count by
  62    the frequency gives you seconds between the interval, then
  63    multiplying by 1000000000 gives you nanoseconds.  Of course,
  64    you should do the multiply first, then the divide to reduce
  65    arithmetic errors due to integer math.  But since we want the
  66    least amount of math in the critical path as possible and
  67    mach_absolute_time is already a cycle counter, we claim we have
  68    native cycle count support and set the frequencey to be the
  69    frequencey of the global clock, which is sTBI.denom *
  70    (1000000000 / sTBI.numer), which is sTBI.denom * (1 / 1), or
  71    sTBI.denom.
  72 
  73    On Intel, mach_timebase_info returns numer = 1 nd denom = 1,
  74    meaning that mach_absolute_time() returns some global clock
  75    time in nanoseconds.  Because PPC returns a frequency and
  76    returning a time in microseconds would still require math in
  77    the critical path (a divide, at that), we pretend that the
  78    nanosecond timer is instead a cycle counter for a 1GHz clock
  79    and that we're returning a cycle count natively.  so sTBI.denom
  80    * (1000000000 / sTBI.numer) gives us 1 * (1000000000 / 1), or
  81    1000000000, meaning we have a 1GHz clock.
  82 
  83    More generally, since mach_timebase_info() gives the "keys" to
  84    transition the return from mach_absolute_time() into
  85    nanoseconds, taking the reverse of that and multipling by
  86    1000000000 will give you a frequency in cycles / second if you
  87    think of mach_absolute_time() always returning a cycle count.
  88 */
  89 int opal_timer_darwin_open(void)
  90 {
  91     /* Call the opal_timer_base_get_cycles once to start the enging */
  92     (void)opal_timer_base_get_cycles();
  93 
  94     opal_timer_darwin_freq = opal_timer_darwin_info.denom * (1000000000 / opal_timer_darwin_info.numer);
  95 
  96     return OPAL_SUCCESS;
  97 }

/* [<][>][^][v][top][bottom][index][help] */