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

       1                 : /*
       2                 :  * Copyright (c) 2013 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/trusted/service_runtime/osx/mach_thread_map.h"
       8                 : 
       9                 : #include <pthread.h>
      10                 : 
      11                 : #include "native_client/src/shared/platform/nacl_check.h"
      12                 : #include "native_client/src/trusted/service_runtime/arch/sel_ldr_arch.h"
      13                 : #include "native_client/src/trusted/service_runtime/nacl_globals.h"
      14                 : 
      15                 : #if NACL_ARCH(NACL_BUILD_ARCH) == NACL_x86 && NACL_BUILD_SUBARCH == 64
      16                 : 
      17                 : static mach_port_t mach_threads[NACL_THREAD_MAX];
      18                 : 
      19           56457 : uint32_t NaClGetThreadIndexForMachThread(mach_port_t mach_thread) {
      20           56457 :   uint32_t nacl_thread_index;
      21                 : 
      22          225828 :   DCHECK(mach_thread != MACH_PORT_NULL);
      23                 : 
      24          112914 :   CHECK(NACL_TLS_INDEX_INVALID < NACL_THREAD_MAX);  /* Skip the invalid slot. */
      25       336841016 :   for (nacl_thread_index = NACL_TLS_INDEX_INVALID + 1;
      26                 :        nacl_thread_index < NACL_THREAD_MAX;
      27       336847563 :        ++nacl_thread_index) {
      28       336751961 :     if (mach_threads[nacl_thread_index] == mach_thread) {
      29           15017 :       return nacl_thread_index;
      30                 :     }
      31       336829356 :   }
      32                 : 
      33           41439 :   return NACL_TLS_INDEX_INVALID;
      34           56456 : }
      35                 : 
      36           20875 : void NaClSetCurrentMachThreadForThreadIndex(uint32_t nacl_thread_index) {
      37                 :   /*
      38                 :    * This implementation relies on the Mach port for the thread stored by the
      39                 :    * pthread library, and assumes that the pthread library does not close and
      40                 :    * re-acquire the Mach port for the thread. If that happens, Mach could
      41                 :    * theoretically assign the port a different number in the process' port
      42                 :    * table. This approach avoids having to deal with ownership of the port and
      43                 :    * the system call overhad to obtain and deallocate it as would be the case
      44                 :    * with mach_thread_self().
      45                 :    *
      46                 :    * When used by the Mach exception handler, this also assumes that the
      47                 :    * thread port number when received for an exception will match the port
      48                 :    * stored in the mach_threads table. This is guaranteed by how the kernel
      49                 :    * coalesces ports in a single port namespace. (A task, or process, is a
      50                 :    * single port namespace.)
      51                 :    *
      52                 :    * An alternative implementation that works on Mac OS X 10.6 or higher is to
      53                 :    * use pthread_threadid_np() to obtain a thread ID to use as the key for
      54                 :    * this thread map. Such thread IDs are unique system-wide. An exception
      55                 :    * handler can find the thread ID for a Mach thread by calling thread_info()
      56                 :    * with flavor THREAD_IDENTIFIER_INFO. This approach is not used here
      57                 :    * because of the added system call overhead at exception time.
      58                 :    */
      59           20875 :   mach_port_t mach_thread = pthread_mach_thread_np(pthread_self());
      60           62629 :   CHECK(mach_thread != MACH_PORT_NULL);
      61                 : 
      62          104383 :   DCHECK(nacl_thread_index > NACL_TLS_INDEX_INVALID &&
      63                 :          nacl_thread_index < NACL_THREAD_MAX);
      64           83508 :   DCHECK(mach_threads[nacl_thread_index] == MACH_PORT_NULL);
      65           83510 :   DCHECK(NaClGetThreadIndexForMachThread(mach_thread) ==
      66                 :          NACL_TLS_INDEX_INVALID);
      67                 : 
      68           20878 :   mach_threads[nacl_thread_index] = mach_thread;
      69           20878 : }
      70                 : 
      71           20561 : void NaClClearMachThreadForThreadIndex(uint32_t nacl_thread_index) {
      72           20561 :   mach_port_t mach_thread = mach_threads[nacl_thread_index];
      73                 : 
      74          102805 :   DCHECK(nacl_thread_index > NACL_TLS_INDEX_INVALID &&
      75                 :          nacl_thread_index < NACL_THREAD_MAX);
      76           82244 :   DCHECK(mach_thread == pthread_mach_thread_np(pthread_self()));
      77                 : 
      78           20561 :   mach_threads[nacl_thread_index] = MACH_PORT_NULL;
      79                 : 
      80           82242 :   DCHECK(NaClGetThreadIndexForMachThread(mach_thread) ==
      81                 :          NACL_TLS_INDEX_INVALID);
      82           20560 : }
      83                 : 
      84                 : #endif

Generated by: LCOV version 1.7