15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/platform_thread.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <errno.h> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sched.h> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/lazy_instance.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/safe_strerror_posix.h" 1490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)#include "base/synchronization/waitable_event.h" 152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread_id_name_manager.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread_restrictions.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/tracked_objects.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h> 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/prctl.h> 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/resource.h> 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/syscall.h> 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <sys/time.h> 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <unistd.h> 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace base { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void InitThreading(); 3590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void InitOnThread(); 3690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)void TerminateOnThread(); 3790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes); 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)struct ThreadParams { 4290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadParams() 4390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) : delegate(NULL), 4490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) joinable(false), 4590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) priority(kThreadPriority_Normal), 4690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) handle(NULL), 4790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) handle_set(false, false) { 4890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 4990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThread::Delegate* delegate; 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool joinable; 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ThreadPriority priority; 5390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThreadHandle* handle; 5490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) WaitableEvent handle_set; 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void* ThreadFunc(void* params) { 5890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::InitOnThread(); 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadParams* thread_params = static_cast<ThreadParams*>(params); 6090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThread::Delegate* delegate = thread_params->delegate; 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!thread_params->joinable) 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::SetSingletonAllowed(false); 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 6590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (thread_params->priority != kThreadPriority_Normal) { 6690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThread::SetThreadPriority(PlatformThread::CurrentHandle(), 6790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_params->priority); 6890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) } 6990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Stash the id in the handle so the calling thread has a complete 7190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // handle, and unblock the parent thread. 7290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) *(thread_params->handle) = PlatformThreadHandle(pthread_self(), 7390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThread::CurrentId()); 7490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) thread_params->handle_set.Signal(); 7590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 7690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadIdNameManager::GetInstance()->RegisterThread( 7790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThread::CurrentHandle().platform_handle(), 7890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThread::CurrentId()); 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate->ThreadMain(); 8190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadIdNameManager::GetInstance()->RemoveName( 8390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThread::CurrentHandle().platform_handle(), 8490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) PlatformThread::CurrentId()); 8590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 8690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::TerminateOnThread(); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return NULL; 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool CreateThread(size_t stack_size, bool joinable, 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThread::Delegate* delegate, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThreadHandle* thread_handle, 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadPriority priority) { 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::InitThreading(); 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = false; 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_attr_t attributes; 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_attr_init(&attributes); 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Pthreads are joinable by default, so only specify the detached 10190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // attribute if the thread should be non-joinable. 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!joinable) { 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_attr_setdetachstate(&attributes, PTHREAD_CREATE_DETACHED); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Get a better default if available. 10790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (stack_size == 0) 10890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) stack_size = base::GetDefaultThreadStackSize(attributes); 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (stack_size > 0) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_attr_setstacksize(&attributes, stack_size); 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadParams params; 11490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.delegate = delegate; 11590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.joinable = joinable; 11690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.priority = priority; 11790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.handle = thread_handle; 11890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 119cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) pthread_t handle; 12090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) int err = pthread_create(&handle, 12190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) &attributes, 12290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ThreadFunc, 12390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ¶ms); 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) success = !err; 1252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!success) { 126cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) // Value of |handle| is undefined if pthread_create fails. 127cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) handle = 0; 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) errno = err; 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PLOG(ERROR) << "pthread_create"; 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pthread_attr_destroy(&attributes); 13390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 13490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // Don't let this call complete until the thread id 13590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) // is set in the handle. 13690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) if (success) 13790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) params.handle_set.Wait(); 13890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) CHECK_EQ(handle, thread_handle->platform_handle()); 13990dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return success; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)PlatformThreadId PlatformThread::CurrentId() { 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pthreads doesn't have the concept of a thread ID, so we have to reach down 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // into the kernel. 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_MACOSX) 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return pthread_mach_thread_np(pthread_self()); 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_LINUX) 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return syscall(__NR_gettid); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_ANDROID) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return gettid(); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#elif defined(OS_SOLARIS) || defined(OS_QNX) 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pthread_self(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_NACL) && defined(__GLIBC__) 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return pthread_self(); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_NACL) && !defined(__GLIBC__) 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Pointers are 32-bits in NaCl. 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<int32>(pthread_self()); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_POSIX) 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return reinterpret_cast<int64>(pthread_self()); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 167cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 168cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)PlatformThreadRef PlatformThread::CurrentRef() { 169cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return PlatformThreadRef(pthread_self()); 170cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)} 171cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 172cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)// static 17390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)PlatformThreadHandle PlatformThread::CurrentHandle() { 17490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) return PlatformThreadHandle(pthread_self(), CurrentId()); 17590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)} 17690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::YieldCurrentThread() { 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sched_yield(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::Sleep(TimeDelta duration) { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) struct timespec sleep_time, remaining; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Break the duration into seconds and nanoseconds. 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // NOTE: TimeDelta's microseconds are int64s while timespec's 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // nanoseconds are longs, so this unpacking must prevent overflow. 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sleep_time.tv_sec = duration.InSeconds(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) duration -= TimeDelta::FromSeconds(sleep_time.tv_sec); 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sleep_time.tv_nsec = duration.InMicroseconds() * 1000; // nanoseconds 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (nanosleep(&sleep_time, &remaining) == -1 && errno == EINTR) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sleep_time = remaining; 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char* PlatformThread::GetName() { 1992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return ThreadIdNameManager::GetInstance()->GetName(CurrentId()); 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformThread::Create(size_t stack_size, Delegate* delegate, 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThreadHandle* thread_handle) { 20590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateThread(stack_size, true /* joinable thread */, 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate, thread_handle, kThreadPriority_Normal); 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformThread::CreateWithPriority(size_t stack_size, Delegate* delegate, 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThreadHandle* thread_handle, 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ThreadPriority priority) { 21490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return CreateThread(stack_size, true, // joinable thread 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate, thread_handle, priority); 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool PlatformThread::CreateNonJoinable(size_t stack_size, Delegate* delegate) { 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PlatformThreadHandle unused; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 22390dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) base::ThreadRestrictions::ScopedAllowWait allow_wait; 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool result = CreateThread(stack_size, false /* non-joinable thread */, 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delegate, &unused, kThreadPriority_Normal); 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void PlatformThread::Join(PlatformThreadHandle thread_handle) { 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Joining another thread may block the current thread for a long time, since 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the thread referred to by |thread_handle| may still be running long-lived / 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // blocking tasks. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ThreadRestrictions::AssertIOAllowed(); 235d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) CHECK_EQ(0, pthread_join(thread_handle.handle_, NULL)); 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace base 239