chromium/base/threading/platform_thread_posix.cc

// Copyright 2012 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/threading/platform_thread.h"

#include <errno.h>
#include <pthread.h>
#include <sched.h>
#include <stddef.h>
#include <stdint.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

#include <memory>
#include <tuple>

#include "base/compiler_specific.h"
#include "base/lazy_instance.h"
#include "base/logging.h"
#include "base/memory/raw_ptr.h"
#include "base/notimplemented.h"
#include "base/threading/platform_thread_internal_posix.h"
#include "base/threading/scoped_blocking_call.h"
#include "base/threading/thread_id_name_manager.h"
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "partition_alloc/buildflags.h"

#if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_FUCHSIA) && !BUILDFLAG(IS_NACL)
#include "base/posix/can_lower_nice_to.h"
#endif

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
#include <sys/syscall.h>
#include <atomic>
#endif

#if BUILDFLAG(IS_FUCHSIA)
#include <lib/zx/thread.h>

#include "base/fuchsia/koid.h"
#else
#include <sys/resource.h>
#endif

#if PA_BUILDFLAG(USE_PARTITION_ALLOC_AS_MALLOC)
#include "partition_alloc/stack/stack.h"
#endif

namespace base {

void InitThreading();
void TerminateOnThread();
size_t GetDefaultThreadStackSize(const pthread_attr_t& attributes);

namespace {

struct ThreadParams {};

void* ThreadFunc(void* params) {}

bool CreateThread(size_t stack_size,
                  bool joinable,
                  PlatformThread::Delegate* delegate,
                  PlatformThreadHandle* thread_handle,
                  ThreadType thread_type,
                  MessagePumpType message_pump_type) {}

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

// Store the thread ids in local storage since calling the SWI can be
// expensive and PlatformThread::CurrentId is used liberally.
thread_local pid_t g_thread_id =;

// A boolean value that indicates that the value stored in |g_thread_id| on the
// main thread is invalid, because it hasn't been updated since the process
// forked.
//
// This used to work by setting |g_thread_id| to -1 in a pthread_atfork handler.
// However, when a multithreaded process forks, it is only allowed to call
// async-signal-safe functions until it calls an exec() syscall. However,
// accessing TLS may allocate (see crbug.com/1275748), which is not
// async-signal-safe and therefore causes deadlocks, corruption, and crashes.
//
// It's Atomic to placate TSAN.
std::atomic<bool> g_main_thread_tid_cache_valid =;

// Tracks whether the current thread is the main thread, and therefore whether
// |g_main_thread_tid_cache_valid| is relevant for the current thread. This is
// also updated by PlatformThread::CurrentId().
thread_local bool g_is_main_thread =;

class InitAtFork {};

#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

}  // namespace

#if BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

namespace internal {

void InvalidateTidCache() {}

}  // namespace internal

#endif  // BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)

// static
PlatformThreadId PlatformThreadBase::CurrentId() {}

// static
PlatformThreadRef PlatformThreadBase::CurrentRef() {}

// static
PlatformThreadHandle PlatformThreadBase::CurrentHandle() {}

#if !BUILDFLAG(IS_APPLE)
// static
void PlatformThreadBase::YieldCurrentThread() {}
#endif  // !BUILDFLAG(IS_APPLE)

// static
void PlatformThreadBase::Sleep(TimeDelta duration) {}

// static
const char* PlatformThreadBase::GetName() {}

// static
bool PlatformThreadBase::CreateWithType(size_t stack_size,
                                    Delegate* delegate,
                                    PlatformThreadHandle* thread_handle,
                                    ThreadType thread_type,
                                    MessagePumpType pump_type_hint) {}

// static
bool PlatformThreadBase::CreateNonJoinable(size_t stack_size, Delegate* delegate) {}

// static
bool PlatformThreadBase::CreateNonJoinableWithType(size_t stack_size,
                                               Delegate* delegate,
                                               ThreadType thread_type,
                                               MessagePumpType pump_type_hint) {}

// static
void PlatformThreadBase::Join(PlatformThreadHandle thread_handle) {}

// static
void PlatformThreadBase::Detach(PlatformThreadHandle thread_handle) {}

// Mac and Fuchsia have their own SetCurrentThreadType() and
// GetCurrentThreadPriorityForTest() implementations.
#if !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_FUCHSIA)

// static
bool PlatformThreadBase::CanChangeThreadType(ThreadType from, ThreadType to) {}

namespace internal {

void SetCurrentThreadTypeImpl(ThreadType thread_type,
                              MessagePumpType pump_type_hint) {}

}  // namespace internal

// static
ThreadPriorityForTest PlatformThreadBase::GetCurrentThreadPriorityForTest() {}

#endif  // !BUILDFLAG(IS_APPLE) && !BUILDFLAG(IS_FUCHSIA)

// static
size_t PlatformThreadBase::GetDefaultThreadStackSize() {}

}  // namespace base