ipc/chromium/src/base/platform_thread_posix.cc

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/ipc/chromium/src/base/platform_thread_posix.cc	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,171 @@
     1.4 +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
     1.5 +// Use of this source code is governed by a BSD-style license that can be
     1.6 +// found in the LICENSE file.
     1.7 +
     1.8 +#include "base/platform_thread.h"
     1.9 +
    1.10 +#include <errno.h>
    1.11 +#include <sched.h>
    1.12 +
    1.13 +#if defined(OS_MACOSX)
    1.14 +#include <mach/mach.h>
    1.15 +#elif defined(OS_NETBSD)
    1.16 +#include <lwp.h>
    1.17 +#elif defined(OS_LINUX)
    1.18 +#include <sys/syscall.h>
    1.19 +#include <sys/prctl.h>
    1.20 +#elif defined(OS_FREEBSD) && !defined(__GLIBC__)
    1.21 +#include <sys/param.h>
    1.22 +#include <sys/thr.h>
    1.23 +#endif
    1.24 +
    1.25 +#if !defined(OS_MACOSX)
    1.26 +#include <unistd.h>
    1.27 +#endif
    1.28 +
    1.29 +#if defined(OS_BSD) && !defined(OS_NETBSD) && !defined(__GLIBC__)
    1.30 +#include <pthread_np.h>
    1.31 +#endif
    1.32 +
    1.33 +#if defined(OS_MACOSX)
    1.34 +namespace base {
    1.35 +void InitThreading();
    1.36 +}  // namespace
    1.37 +#endif
    1.38 +
    1.39 +static void* ThreadFunc(void* closure) {
    1.40 +  PlatformThread::Delegate* delegate =
    1.41 +      static_cast<PlatformThread::Delegate*>(closure);
    1.42 +  delegate->ThreadMain();
    1.43 +  return NULL;
    1.44 +}
    1.45 +
    1.46 +// static
    1.47 +PlatformThreadId PlatformThread::CurrentId() {
    1.48 +  // Pthreads doesn't have the concept of a thread ID, so we have to reach down
    1.49 +  // into the kernel.
    1.50 +#if defined(OS_MACOSX)
    1.51 +  mach_port_t port = mach_thread_self();
    1.52 +  mach_port_deallocate(mach_task_self(), port);
    1.53 +  return port;
    1.54 +#elif defined(OS_LINUX)
    1.55 +#ifdef MOZ_WIDGET_GONK
    1.56 +  return (intptr_t) (pthread_self());
    1.57 +#else
    1.58 +  return syscall(__NR_gettid);
    1.59 +#endif
    1.60 +#elif defined(OS_OPENBSD) || defined(__GLIBC__)
    1.61 +  return (intptr_t) (pthread_self());
    1.62 +#elif defined(OS_NETBSD)
    1.63 +  return _lwp_self();
    1.64 +#elif defined(OS_DRAGONFLY)
    1.65 +  return lwp_gettid();
    1.66 +#elif defined(OS_FREEBSD)
    1.67 +#  if __FreeBSD_version > 900030
    1.68 +    return pthread_getthreadid_np();
    1.69 +#  else
    1.70 +    long lwpid;
    1.71 +    thr_self(&lwpid);
    1.72 +    return lwpid;
    1.73 +#  endif
    1.74 +#endif
    1.75 +}
    1.76 +
    1.77 +// static
    1.78 +void PlatformThread::YieldCurrentThread() {
    1.79 +  sched_yield();
    1.80 +}
    1.81 +
    1.82 +// static
    1.83 +void PlatformThread::Sleep(int duration_ms) {
    1.84 +  struct timespec sleep_time, remaining;
    1.85 +
    1.86 +  // Contains the portion of duration_ms >= 1 sec.
    1.87 +  sleep_time.tv_sec = duration_ms / 1000;
    1.88 +  duration_ms -= sleep_time.tv_sec * 1000;
    1.89 +
    1.90 +  // Contains the portion of duration_ms < 1 sec.
    1.91 +  sleep_time.tv_nsec = duration_ms * 1000 * 1000;  // nanoseconds.
    1.92 +
    1.93 +  while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR)
    1.94 +    sleep_time = remaining;
    1.95 +}
    1.96 +
    1.97 +#ifndef OS_MACOSX
    1.98 +// Mac is implemented in platform_thread_mac.mm.
    1.99 +
   1.100 +// static
   1.101 +void PlatformThread::SetName(const char* name) {
   1.102 +  // On linux we can get the thread names to show up in the debugger by setting
   1.103 +  // the process name for the LWP.  We don't want to do this for the main
   1.104 +  // thread because that would rename the process, causing tools like killall
   1.105 +  // to stop working.
   1.106 +  if (PlatformThread::CurrentId() == getpid())
   1.107 +    return;
   1.108 +
   1.109 +  // http://0pointer.de/blog/projects/name-your-threads.html
   1.110 +  // Set the name for the LWP (which gets truncated to 15 characters).
   1.111 +  // Note that glibc also has a 'pthread_setname_np' api, but it may not be
   1.112 +  // available everywhere and it's only benefit over using prctl directly is
   1.113 +  // that it can set the name of threads other than the current thread.
   1.114 +#if defined(OS_LINUX)
   1.115 +  prctl(PR_SET_NAME, reinterpret_cast<uintptr_t>(name), 0, 0, 0); 
   1.116 +#elif defined(OS_NETBSD)
   1.117 +  pthread_setname_np(pthread_self(), "%s", (void *)name);
   1.118 +#elif defined(OS_BSD) && !defined(__GLIBC__)
   1.119 +  pthread_set_name_np(pthread_self(), name);
   1.120 +#else
   1.121 +#endif
   1.122 +}
   1.123 +#endif // !OS_MACOSX
   1.124 +
   1.125 +namespace {
   1.126 +
   1.127 +bool CreateThread(size_t stack_size, bool joinable,
   1.128 +                  PlatformThread::Delegate* delegate,
   1.129 +                  PlatformThreadHandle* thread_handle) {
   1.130 +#if defined(OS_MACOSX)
   1.131 +  base::InitThreading();
   1.132 +#endif  // OS_MACOSX
   1.133 +
   1.134 +  bool success = false;
   1.135 +  pthread_attr_t attributes;
   1.136 +  pthread_attr_init(&attributes);
   1.137 +
   1.138 +  // Pthreads are joinable by default, so only specify the detached attribute if
   1.139 +  // the thread should be non-joinable.
   1.140 +  if (!joinable) {
   1.141 +    pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED);
   1.142 +  }
   1.143 +
   1.144 +  if (stack_size > 0)
   1.145 +    pthread_attr_setstacksize(&attributes, stack_size);
   1.146 +
   1.147 +  success = !pthread_create(thread_handle, &attributes, ThreadFunc, delegate);
   1.148 +
   1.149 +  pthread_attr_destroy(&attributes);
   1.150 +  return success;
   1.151 +}
   1.152 +
   1.153 +}  // anonymous namespace
   1.154 +
   1.155 +// static
   1.156 +bool PlatformThread::Create(size_t stack_size, Delegate* delegate,
   1.157 +                            PlatformThreadHandle* thread_handle) {
   1.158 +  return CreateThread(stack_size, true /* joinable thread */,
   1.159 +                      delegate, thread_handle);
   1.160 +}
   1.161 +
   1.162 +// static
   1.163 +bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) {
   1.164 +  PlatformThreadHandle unused;
   1.165 +
   1.166 +  bool result = CreateThread(stack_size, false /* non-joinable thread */,
   1.167 +                             delegate, &unused);
   1.168 +  return result;
   1.169 +}
   1.170 +
   1.171 +// static
   1.172 +void PlatformThread::Join(PlatformThreadHandle thread_handle) {
   1.173 +  pthread_join(thread_handle, NULL);
   1.174 +}

mercurial