ipc/chromium/src/base/platform_thread_posix.cc

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

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

mercurial