6#if defined(DART_HOST_OS_MACOS) && !defined(DART_USE_ABSL)
10#include <mach/mach_host.h>
11#include <mach/mach_init.h>
12#include <mach/mach_port.h>
13#include <mach/mach_traps.h>
14#include <mach/task_info.h>
15#include <mach/thread_act.h>
16#include <mach/thread_info.h>
19#include <sys/sysctl.h>
33 worker_thread_priority,
35 "The thread priority the VM should use for new worker threads.");
37#define VALIDATE_PTHREAD_RESULT(result) \
39 const int kBufferSize = 1024; \
40 char error_message[kBufferSize]; \
41 Utils::StrError(result, error_message, kBufferSize); \
42 FATAL("pthread error: %d (%s)", result, error_message); \
46#define VALIDATE_PTHREAD_RESULT_NAMED(result) VALIDATE_PTHREAD_RESULT(result)
48#define VALIDATE_PTHREAD_RESULT_NAMED(result) \
50 const int kBufferSize = 1024; \
51 char error_message[kBufferSize]; \
52 Utils::StrError(result, error_message, kBufferSize); \
53 FATAL("[%s] pthread error: %d (%s)", name_, result, error_message); \
58#define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result)
61#define ASSERT_PTHREAD_SUCCESS(result) ASSERT(result == 0)
65#define RETURN_ON_PTHREAD_FAILURE(result) \
67 const int kBufferSize = 1024; \
68 char error_message[kBufferSize]; \
69 Utils::StrError(result, error_message, kBufferSize); \
70 fprintf(stderr, "%s:%d: pthread error: %d (%s)\n", __FILE__, __LINE__, \
71 result, error_message); \
75#define RETURN_ON_PTHREAD_FAILURE(result) \
76 if (result != 0) return result;
79class ThreadStartData {
81 ThreadStartData(
const char*
name,
84 : name_(
name), function_(
function), parameter_(parameter) {}
86 const char*
name()
const {
return name_; }
88 uword parameter()
const {
return parameter_; }
101static void* ThreadStart(
void* data_ptr) {
102 if (FLAG_worker_thread_priority !=
kMinInt) {
103 const pthread_t thread = pthread_self();
105 struct sched_param schedule;
106 if (pthread_getschedparam(thread, &
policy, &schedule) != 0) {
107 FATAL(
"Obtaining sched param failed: errno = %d\n", errno);
109 schedule.sched_priority = FLAG_worker_thread_priority;
110 if (pthread_setschedparam(thread,
policy, &schedule) != 0) {
111 FATAL(
"Setting thread priority to %d failed: errno = %d\n",
112 FLAG_worker_thread_priority, errno);
116 ThreadStartData*
data =
reinterpret_cast<ThreadStartData*
>(data_ptr);
126 char truncated_name[16];
128 pthread_setname_np(
name);
132 if (thread !=
nullptr) {
134 thread->SetName(
name);
146 int result = pthread_attr_init(&attr);
147 RETURN_ON_PTHREAD_FAILURE(
result);
150 RETURN_ON_PTHREAD_FAILURE(
result);
155 result = pthread_create(&tid, &attr, ThreadStart,
data);
156 RETURN_ON_PTHREAD_FAILURE(
result);
158 result = pthread_attr_destroy(&attr);
159 RETURN_ON_PTHREAD_FAILURE(
result);
170 int result = pthread_key_create(&
key, destructor);
171 VALIDATE_PTHREAD_RESULT(
result);
179 VALIDATE_PTHREAD_RESULT(
result);
184 int result = pthread_setspecific(
key,
reinterpret_cast<void*
>(
value));
185 VALIDATE_PTHREAD_RESULT(
result);
194 return pthread_self();
197#ifdef SUPPORT_TIMELINE
198ThreadId OSThread::GetCurrentThreadTraceId() {
203char* OSThread::GetCurrentThreadName() {
204 const intptr_t kNameBufferSize = 16;
205 char*
name =
static_cast<char*
>(
malloc(kNameBufferSize));
206 pthread_getname_np(pthread_self(),
name, kNameBufferSize);
211 ASSERT(thread !=
nullptr);
216 pthread_t
id = pthread_self();
218 thread->join_id_ =
id;
224 int result = pthread_join(
id,
nullptr);
230 return reinterpret_cast<intptr_t
>(
id);
238 return pthread_equal(
a,
b) != 0;
242 *upper =
reinterpret_cast<uword>(pthread_get_stackaddr_np(pthread_self()));
243 *
lower = *upper - pthread_get_stacksize_np(pthread_self());
247#if defined(USING_SAFE_STACK)
250uword OSThread::GetCurrentSafestackPointer() {
251#error "SAFE_STACK is unsupported on this platform"
257void OSThread::SetCurrentSafestackPointer(
uword ssp) {
258#error "SAFE_STACK is unsupported on this platform"
267 pthread_mutexattr_t attr;
268 int result = pthread_mutexattr_init(&attr);
269 VALIDATE_PTHREAD_RESULT_NAMED(
result);
272 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
273 VALIDATE_PTHREAD_RESULT_NAMED(
result);
276 result = pthread_mutex_init(data_.mutex(), &attr);
278 VALIDATE_PTHREAD_RESULT_NAMED(
result);
280 result = pthread_mutexattr_destroy(&attr);
281 VALIDATE_PTHREAD_RESULT_NAMED(
result);
290 int result = pthread_mutex_destroy(data_.mutex());
292 VALIDATE_PTHREAD_RESULT_NAMED(
result);
301 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
303 int result = pthread_mutex_lock(data_.mutex());
306 ASSERT_PTHREAD_SUCCESS(
result);
313bool Mutex::TryLock() {
314 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
316 int result = pthread_mutex_trylock(data_.mutex());
321 ASSERT_PTHREAD_SUCCESS(
result);
329void Mutex::Unlock() {
335 int result = pthread_mutex_unlock(data_.mutex());
338 ASSERT_PTHREAD_SUCCESS(
result);
342 pthread_mutexattr_t attr;
343 int result = pthread_mutexattr_init(&attr);
344 VALIDATE_PTHREAD_RESULT(
result);
347 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
348 VALIDATE_PTHREAD_RESULT(
result);
351 result = pthread_mutex_init(data_.mutex(), &attr);
352 VALIDATE_PTHREAD_RESULT(
result);
354 result = pthread_mutexattr_destroy(&attr);
355 VALIDATE_PTHREAD_RESULT(
result);
357 result = pthread_cond_init(data_.cond(),
nullptr);
358 VALIDATE_PTHREAD_RESULT(
result);
372 int result = pthread_mutex_destroy(data_.mutex());
373 VALIDATE_PTHREAD_RESULT(
result);
375 result = pthread_cond_destroy(data_.cond());
376 VALIDATE_PTHREAD_RESULT(
result);
379bool Monitor::TryEnter() {
380 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
382 int result = pthread_mutex_trylock(data_.mutex());
387 ASSERT_PTHREAD_SUCCESS(
result);
396void Monitor::Enter() {
397 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
399 int result = pthread_mutex_lock(data_.mutex());
400 VALIDATE_PTHREAD_RESULT(
result);
409void Monitor::Exit() {
416 int result = pthread_mutex_unlock(data_.mutex());
417 VALIDATE_PTHREAD_RESULT(
result);
435 int result = pthread_cond_wait(data_.cond(), data_.mutex());
436 VALIDATE_PTHREAD_RESULT(
result);
446 ts.tv_sec =
static_cast<int32_t
>(secs);
447 ts.tv_nsec =
static_cast<long>(nanos);
449 pthread_cond_timedwait_relative_np(data_.cond(), data_.mutex(), &ts);
451 if (
result == ETIMEDOUT) {
460 ASSERT(owner_ == saved_owner);
465void Monitor::Notify() {
468 int result = pthread_cond_signal(data_.cond());
469 VALIDATE_PTHREAD_RESULT(
result);
472void Monitor::NotifyAll() {
475 int result = pthread_cond_broadcast(data_.cond());
476 VALIDATE_PTHREAD_RESULT(
result);
#define NO_SANITIZE_ADDRESS
#define DEBUG_ASSERT(cond)
bool IsOwnedByCurrentThread() const
static constexpr int64_t kNoTimeout
Mutex(NOT_IN_PRODUCT(const char *name="anonymous mutex"))
bool IsOwnedByCurrentThread() const
static void DeleteThreadLocal(ThreadLocalKey key)
static int Start(const char *name, ThreadStartFunction function, uword parameter)
const char * name() const
static bool GetCurrentStackBounds(uword *lower, uword *upper)
static OSThread * CreateOSThread()
static void SetCurrent(OSThread *current)
static ThreadId ThreadIdFromIntPtr(intptr_t id)
static ThreadId GetCurrentThreadId()
static void Join(ThreadJoinId id)
static bool Compare(ThreadId a, ThreadId b)
static ThreadLocalKey CreateThreadLocal(ThreadDestructor destructor=nullptr)
static const ThreadId kInvalidThreadId
static ThreadJoinId GetCurrentThreadJoinId(OSThread *thread)
void(* ThreadStartFunction)(uword parameter)
static void SetThreadLocal(ThreadLocalKey key, uword value)
static intptr_t ThreadIdToIntPtr(ThreadId id)
static intptr_t GetMaxStackSize()
static const ThreadJoinId kInvalidThreadJoinId
Dart_NativeFunction function
constexpr intptr_t kMicrosecondsPerMillisecond
constexpr intptr_t kMicrosecondsPerSecond
constexpr intptr_t kNanosecondsPerMicrosecond
void * malloc(size_t size)
DEFINE_FLAG(bool, print_cluster_information, false, "Print information about clusters written to snapshot")
void(* ThreadDestructor)(void *parameter)
constexpr int32_t kMaxInt32
constexpr intptr_t kWordSize
pthread_key_t ThreadLocalKey
static int8_t data[kExtLength]
NOT_IN_PRODUCT(LibraryPtr ReloadTestScript(const char *script))
static const ThreadLocalKey kUnsetThreadLocalKey
COMPILE_ASSERT(kUnreachableReference==WeakTable::kNoValue)
it will be possible to load the file into Perfetto s trace viewer disable asset Prevents usage of any non test fonts unless they were explicitly Loaded via prefetched default font Indicates whether the embedding started a prefetch of the default font manager before creating the engine run In non interactive keep the shell running after the Dart script has completed enable serial On low power devices with low core running concurrent GC tasks on threads can cause them to contend with the UI thread which could potentially lead to jank This option turns off all concurrent GC activities domain network policy
#define NO_SANITIZE_SAFE_STACK
#define ARRAY_SIZE(array)