LCOV - code coverage report
Current view: directory - src/trusted/service_runtime/osx - nacl_thread_nice.c (source / functions) Found Hit Coverage
Test: coverage.lcov Lines: 45 3 6.7 %
Date: 2014-06-18 Functions: 0 0 -

       1                 : /*
       2                 :  * Copyright 2009 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                 :  * Mac OSX thread priority support.
       8                 :  */
       9                 : 
      10                 : #include <mach/mach_init.h>
      11                 : #include <mach/mach_time.h>
      12                 : #include <mach/thread_policy.h>
      13                 : #include <mach/thread_act.h>
      14                 : #include <pthread.h>
      15                 : 
      16                 : #include "native_client/src/shared/platform/nacl_log.h"
      17                 : #include "native_client/src/trusted/service_runtime/include/sys/nacl_nice.h"
      18                 : 
      19                 : /* MyConvertToHostTime converts nanoseconds to the time base used by MacOS.
      20                 :  * Typically the time base is nanoseconds, and the conversion is trivial.
      21                 :  * To avoid having to drag in the entire CoreAudio framework just for this
      22                 :  * subroutine, it is reimplemented here in terms of mach_timebase_info which
      23                 :  * is in the MacOS core.
      24                 :  * To understand that this implementation is correct, have a look at
      25                 :  * CAHostTimeBase::ConvertFromNanos(uint64 inNanos) in CAHostTimeBase.h
      26                 :  */
      27                 : static struct mach_timebase_info gTimeBase;
      28                 : void NaClThreadNiceInit(void) {
      29             275 :   if (mach_timebase_info(&gTimeBase) != KERN_SUCCESS) {
      30               0 :     NaClLog(LOG_WARNING, "mach_timebase_info failed\n");
      31               0 :     gTimeBase.numer = 1;
      32               0 :     gTimeBase.denom = 1;
      33               0 :   }
      34             275 :   if (gTimeBase.denom == 0) {
      35               0 :     NaClLog(LOG_WARNING, "mach_timebase_info returned bogus result\n");
      36               0 :     gTimeBase.numer = 1;
      37               0 :     gTimeBase.denom = 1;
      38               0 :   }
      39             275 : }
      40                 : 
      41               0 : static uint64_t MyConvertToHostTime(uint64_t nanos) {
      42               0 :   double math_tmp = 0.0;
      43                 : 
      44               0 :   math_tmp = gTimeBase.numer;
      45               0 :   math_tmp *= nanos;
      46               0 :   math_tmp /= gTimeBase.denom;
      47               0 :   return (uint64_t)math_tmp;
      48                 : }
      49                 : 
      50               0 : int nacl_thread_nice(int nacl_nice) {
      51               0 :   kern_return_t kr;
      52                 : 
      53                 :   /*
      54                 :    * Don't use mach_thread_self() because it requires a separate
      55                 :    * mach_port_deallocate() system call to release it. Instead, rely on
      56                 :    * pthread's cached copy of the port.
      57                 :    */
      58               0 :   thread_act_t mthread = pthread_mach_thread_np(pthread_self());
      59                 : 
      60               0 :   switch (nacl_nice) {
      61                 :     case NICE_REALTIME: {
      62               0 :       struct thread_time_constraint_policy tcpolicy;
      63               0 :       const int kPeriodInNanoseconds = 2902490;
      64               0 :       const float kDutyCycle = 0.5;
      65               0 :       const float kDutyMax = 0.85;
      66               0 :       tcpolicy.period = MyConvertToHostTime(kPeriodInNanoseconds);
      67               0 :       tcpolicy.computation = kDutyCycle * tcpolicy.period;
      68               0 :       tcpolicy.constraint = kDutyMax * tcpolicy.period;
      69               0 :       tcpolicy.preemptible = 1;
      70                 :       /* Sadly it appears that a MacOS system can be locked up by too
      71                 :        * many real-time threads. So use normal priority until we figure
      72                 :        * out a way to control things globally.
      73                 :        */
      74                 :       /* kr = thread_policy_set(mthread, THREAD_TIME_CONSTRAINT_POLICY,
      75                 :        *                        (thread_policy_t)&tcpolicy,
      76                 :        *                        THREAD_TIME_CONSTRAINT_POLICY_COUNT);
      77                 :        */
      78               0 :       kr = thread_policy_set(mthread, THREAD_PRECEDENCE_POLICY,
      79                 :                              (thread_policy_t)&tcpolicy,
      80                 :                              THREAD_PRECEDENCE_POLICY_COUNT);
      81                 :     }
      82               0 :       break;
      83                 :     case NICE_BACKGROUND: {
      84               0 :       struct thread_precedence_policy tppolicy;
      85               0 :       tppolicy.importance = 0;  /* IDLE_PRI */
      86               0 :       kr = thread_policy_set(mthread, THREAD_PRECEDENCE_POLICY,
      87                 :                              (thread_policy_t)&tppolicy,
      88                 :                              THREAD_PRECEDENCE_POLICY_COUNT);
      89                 :     }
      90               0 :       break;
      91                 :     case NICE_NORMAL: {
      92               0 :       struct thread_standard_policy tspolicy;
      93               0 :       kr = thread_policy_set(mthread, THREAD_STANDARD_POLICY,
      94                 :                              (thread_policy_t)&tspolicy,
      95                 :                              THREAD_STANDARD_POLICY_COUNT);
      96                 :     }
      97               0 :       break;
      98                 :     default:
      99               0 :       NaClLog(LOG_WARNING, "nacl_thread_nice() failed (bad nice value).\n");
     100               0 :       return -1;
     101                 :       break;
     102                 :   }
     103               0 :   if (kr != KERN_SUCCESS) {
     104               0 :     NaClLog(LOG_WARNING, "nacl_thread_nice() failed.\n");
     105               0 :     return -1;
     106                 :   } else {
     107               0 :     return 0;
     108                 :   }
     109               0 : }

Generated by: LCOV version 1.7