LCOV - code coverage report
Current view: top level - ipc/chromium/src/base - platform_thread_posix.cc (source / functions) Hit Total Coverage
Test: output.info Lines: 18 38 47.4 %
Date: 2017-07-14 16:53:18 Functions: 5 9 55.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2             : /* vim: set ts=8 sts=2 et sw=2 tw=80: */
       3             : // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
       4             : // Use of this source code is governed by a BSD-style license that can be
       5             : // found in the LICENSE file.
       6             : 
       7             : #include "base/platform_thread.h"
       8             : 
       9             : #include <errno.h>
      10             : #include <sched.h>
      11             : 
      12             : #if defined(OS_MACOSX)
      13             : #include <mach/mach.h>
      14             : #elif defined(OS_NETBSD)
      15             : #include <lwp.h>
      16             : #elif defined(OS_LINUX)
      17             : #include <sys/syscall.h>
      18             : #include <sys/prctl.h>
      19             : #endif
      20             : 
      21             : #if !defined(OS_MACOSX)
      22             : #include <unistd.h>
      23             : #endif
      24             : 
      25             : #if defined(OS_BSD) && !defined(OS_NETBSD) && !defined(__GLIBC__)
      26             : #include <pthread_np.h>
      27             : #endif
      28             : 
      29             : #if defined(OS_MACOSX)
      30             : namespace base {
      31             : void InitThreading();
      32             : }  // namespace
      33             : #endif
      34             : 
      35           8 : static void* ThreadFunc(void* closure) {
      36             :   PlatformThread::Delegate* delegate =
      37           8 :       static_cast<PlatformThread::Delegate*>(closure);
      38           8 :   delegate->ThreadMain();
      39           0 :   return NULL;
      40             : }
      41             : 
      42             : // static
      43       10867 : PlatformThreadId PlatformThread::CurrentId() {
      44             :   // Pthreads doesn't have the concept of a thread ID, so we have to reach down
      45             :   // into the kernel.
      46             : #if defined(OS_MACOSX)
      47             :   mach_port_t port = mach_thread_self();
      48             :   mach_port_deallocate(mach_task_self(), port);
      49             :   return port;
      50             : #elif defined(OS_LINUX)
      51             : #ifdef MOZ_WIDGET_GONK
      52             :   return (intptr_t) (pthread_self());
      53             : #else
      54       10867 :   return syscall(__NR_gettid);
      55             : #endif
      56             : #elif defined(OS_OPENBSD) || defined(OS_SOLARIS) || defined(__GLIBC__)
      57             :   return (intptr_t) (pthread_self());
      58             : #elif defined(OS_NETBSD)
      59             :   return _lwp_self();
      60             : #elif defined(OS_DRAGONFLY)
      61             :   return lwp_gettid();
      62             : #elif defined(OS_FREEBSD)
      63             :   return pthread_getthreadid_np();
      64             : #endif
      65             : }
      66             : 
      67             : // static
      68           0 : void PlatformThread::YieldCurrentThread() {
      69           0 :   sched_yield();
      70           0 : }
      71             : 
      72             : // static
      73           0 : void PlatformThread::Sleep(int duration_ms) {
      74             :   struct timespec sleep_time, remaining;
      75             : 
      76             :   // Contains the portion of duration_ms >= 1 sec.
      77           0 :   sleep_time.tv_sec = duration_ms / 1000;
      78           0 :   duration_ms -= sleep_time.tv_sec * 1000;
      79             : 
      80             :   // Contains the portion of duration_ms < 1 sec.
      81           0 :   sleep_time.tv_nsec = duration_ms * 1000 * 1000;  // nanoseconds.
      82             : 
      83           0 :   while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
      84           0 :     sleep_time = remaining;
      85           0 : }
      86             : 
      87             : #ifndef OS_MACOSX
      88             : // Mac is implemented in platform_thread_mac.mm.
      89             : 
      90             : // static
      91           8 : void PlatformThread::SetName(const char* name) {
      92             :   // On linux we can get the thread names to show up in the debugger by setting
      93             :   // the process name for the LWP.  We don't want to do this for the main
      94             :   // thread because that would rename the process, causing tools like killall
      95             :   // to stop working.
      96           8 :   if (PlatformThread::CurrentId() == getpid())
      97           0 :     return;
      98             : 
      99             :   // http://0pointer.de/blog/projects/name-your-threads.html
     100             :   // Set the name for the LWP (which gets truncated to 15 characters).
     101             :   // Note that glibc also has a 'pthread_setname_np' api, but it may not be
     102             :   // available everywhere and it's only benefit over using prctl directly is
     103             :   // that it can set the name of threads other than the current thread.
     104             : #if defined(OS_LINUX)
     105           8 :   prctl(PR_SET_NAME, reinterpret_cast<uintptr_t>(name), 0, 0, 0); 
     106             : #elif defined(OS_NETBSD)
     107             :   pthread_setname_np(pthread_self(), "%s", (void *)name);
     108             : #elif defined(OS_BSD) && !defined(__GLIBC__)
     109             :   pthread_set_name_np(pthread_self(), name);
     110             : #elif defined(OS_SOLARIS)
     111             :   pthread_setname_np(pthread_self(), name);
     112             : #else
     113             : #endif
     114             : }
     115             : #endif // !OS_MACOSX
     116             : 
     117             : namespace {
     118             : 
     119           8 : bool CreateThread(size_t stack_size, bool joinable,
     120             :                   PlatformThread::Delegate* delegate,
     121             :                   PlatformThreadHandle* thread_handle) {
     122             : #if defined(OS_MACOSX)
     123             :   base::InitThreading();
     124             : #endif  // OS_MACOSX
     125             : 
     126           8 :   bool success = false;
     127             :   pthread_attr_t attributes;
     128           8 :   pthread_attr_init(&attributes);
     129             : 
     130             :   // Pthreads are joinable by default, so only specify the detached attribute if
     131             :   // the thread should be non-joinable.
     132           8 :   if (!joinable) {
     133           0 :     pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
     134             :   }
     135             : 
     136           8 :   if (stack_size > 0)
     137           0 :     pthread_attr_setstacksize(&attributes, stack_size);
     138             : 
     139           8 :   success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate);
     140             : 
     141           8 :   pthread_attr_destroy(&attributes);
     142           8 :   return success;
     143             : }
     144             : 
     145             : }  // anonymous namespace
     146             : 
     147             : // static
     148           8 : bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
     149             :                             PlatformThreadHandle* thread_handle) {
     150             :   return CreateThread(stack_size, true /* joinable thread */,
     151           8 :                       delegate, thread_handle);
     152             : }
     153             : 
     154             : // static
     155           0 : bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
     156             :   PlatformThreadHandle unused;
     157             : 
     158             :   bool result = CreateThread(stack_size, false /* non-joinable thread */,
     159           0 :                              delegate, &unused);
     160           0 :   return result;
     161             : }
     162             : 
     163             : // static
     164           0 : void PlatformThread::Join(PlatformThreadHandle thread_handle) {
     165           0 :   pthread_join(thread_handle, NULL);
     166           0 : }

Generated by: LCOV version 1.13