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.

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

mercurial