6#if defined(DART_HOST_OS_FUCHSIA) && !defined(DART_USE_ABSL)
13#include <zircon/status.h>
14#include <zircon/syscalls.h>
15#include <zircon/threads.h>
16#include <zircon/tls.h>
17#include <zircon/types.h>
25#define VALIDATE_PTHREAD_RESULT(result) \
27 FATAL("pthread error: %d", result); \
31#define VALIDATE_PTHREAD_RESULT_NAMED(result) VALIDATE_PTHREAD_RESULT(result)
33#define VALIDATE_PTHREAD_RESULT_NAMED(result) \
35 FATAL("[%s] pthread error: %d", name_, result); \
40#define ASSERT_PTHREAD_SUCCESS(result) VALIDATE_PTHREAD_RESULT(result)
43#define ASSERT_PTHREAD_SUCCESS(result) ASSERT(result == 0)
47#define RETURN_ON_PTHREAD_FAILURE(result) \
49 fprintf(stderr, "%s:%d: pthread error: %d\n", __FILE__, __LINE__, result); \
53#define RETURN_ON_PTHREAD_FAILURE(result) \
54 if (result != 0) return result;
57static void ComputeTimeSpecMicros(
struct timespec* ts, int64_t micros) {
59 zx_time_t now = zx_clock_get_monotonic();
68class ThreadStartData {
70 ThreadStartData(
const char*
name,
73 : name_(
name), function_(
function), parameter_(parameter) {}
75 const char*
name()
const {
return name_; }
77 uword parameter()
const {
return parameter_; }
90static void* ThreadStart(
void* data_ptr) {
91 ThreadStartData*
data =
reinterpret_cast<ThreadStartData*
>(data_ptr);
99 char truncated_name[ZX_MAX_NAME_LEN];
100 snprintf(truncated_name, ZX_MAX_NAME_LEN,
"%s",
name);
101 zx_handle_t thread_handle = thrd_get_zx_handle(thrd_current());
102 zx_object_set_property(thread_handle, ZX_PROP_NAME, truncated_name,
107 if (thread !=
nullptr) {
109 thread->SetName(
name);
121 int result = pthread_attr_init(&attr);
122 RETURN_ON_PTHREAD_FAILURE(
result);
125 RETURN_ON_PTHREAD_FAILURE(
result);
130 result = pthread_create(&tid, &attr, ThreadStart,
data);
131 RETURN_ON_PTHREAD_FAILURE(
result);
133 result = pthread_attr_destroy(&attr);
134 RETURN_ON_PTHREAD_FAILURE(
result);
145 int result = pthread_key_create(&
key, destructor);
146 VALIDATE_PTHREAD_RESULT(
result);
154 VALIDATE_PTHREAD_RESULT(
result);
159 int result = pthread_setspecific(
key,
reinterpret_cast<void*
>(
value));
160 VALIDATE_PTHREAD_RESULT(
result);
169 return thrd_get_zx_handle(thrd_current());
172#ifdef SUPPORT_TIMELINE
173ThreadId OSThread::GetCurrentThreadTraceId() {
174 return pthread_self();
178char* OSThread::GetCurrentThreadName() {
179 char*
name =
static_cast<char*
>(
malloc(ZX_MAX_NAME_LEN));
180 zx_handle_t thread_handle = thrd_get_zx_handle(thrd_current());
181 zx_object_get_property(thread_handle, ZX_PROP_NAME,
name, ZX_MAX_NAME_LEN);
186 ASSERT(thread !=
nullptr);
191 pthread_t
id = pthread_self();
193 thread->join_id_ =
id;
199 int result = pthread_join(
id,
nullptr);
205 return static_cast<intptr_t
>(
id);
213 return pthread_equal(
a,
b) != 0;
218 if (pthread_getattr_np(pthread_self(), &attr) != 0) {
225 pthread_attr_destroy(&attr);
235#if defined(USING_SAFE_STACK)
236#define STRINGIFY(s) #s
239uword OSThread::GetCurrentSafestackPointer() {
241#if defined(HOST_ARCH_X64)
242#define _loadfsword(index) "movq %%fs:" STRINGIFY(index) ", %0"
243 asm volatile(_loadfsword(ZX_TLS_UNSAFE_SP_OFFSET)
247#elif defined(HOST_ARCH_ARM64)
248#define _loadword(index) "ldr %0, [%0, " STRINGIFY(index) "]"
249 asm volatile(
"mrs %0, TPIDR_EL0;\n" _loadword(ZX_TLS_UNSAFE_SP_OFFSET)
253#error "Architecture not supported"
260void OSThread::SetCurrentSafestackPointer(
uword ssp) {
261#if defined(HOST_ARCH_X64)
263#define _storefsword(index) "movq %0, %%fs:" str(index)
264 asm volatile(_storefsword(ZX_TLS_UNSAFE_SP_OFFSET)
271#elif defined(HOST_ARCH_ARM64)
272#define _storeword(index) "str %1, [%0, " STRINGIFY(index) "]"
274 asm volatile(
"mrs %0, TPIDR_EL0;\n" _storeword(ZX_TLS_UNSAFE_SP_OFFSET)
280#error "Architecture not supported"
291 pthread_mutexattr_t attr;
292 int result = pthread_mutexattr_init(&attr);
293 VALIDATE_PTHREAD_RESULT_NAMED(
result);
296 result = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);
297 VALIDATE_PTHREAD_RESULT_NAMED(
result);
300 result = pthread_mutex_init(data_.mutex(), &attr);
302 VALIDATE_PTHREAD_RESULT_NAMED(
result);
304 result = pthread_mutexattr_destroy(&attr);
305 VALIDATE_PTHREAD_RESULT_NAMED(
result);
314 int result = pthread_mutex_destroy(data_.mutex());
316 VALIDATE_PTHREAD_RESULT_NAMED(
result);
325 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
327 int result = pthread_mutex_lock(data_.mutex());
330 ASSERT_PTHREAD_SUCCESS(
result);
337bool Mutex::TryLock() {
338 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
340 int result = pthread_mutex_trylock(data_.mutex());
345 ASSERT_PTHREAD_SUCCESS(
result);
353void Mutex::Unlock() {
359 int result = pthread_mutex_unlock(data_.mutex());
362 ASSERT_PTHREAD_SUCCESS(
result);
366 pthread_mutexattr_t mutex_attr;
367 int result = pthread_mutexattr_init(&mutex_attr);
368 VALIDATE_PTHREAD_RESULT(
result);
371 result = pthread_mutexattr_settype(&mutex_attr, PTHREAD_MUTEX_ERRORCHECK);
372 VALIDATE_PTHREAD_RESULT(
result);
375 result = pthread_mutex_init(data_.mutex(), &mutex_attr);
376 VALIDATE_PTHREAD_RESULT(
result);
378 result = pthread_mutexattr_destroy(&mutex_attr);
379 VALIDATE_PTHREAD_RESULT(
result);
381 pthread_condattr_t cond_attr;
382 result = pthread_condattr_init(&cond_attr);
383 VALIDATE_PTHREAD_RESULT(
result);
385 result = pthread_condattr_setclock(&cond_attr, CLOCK_MONOTONIC);
386 VALIDATE_PTHREAD_RESULT(
result);
388 result = pthread_cond_init(data_.cond(), &cond_attr);
389 VALIDATE_PTHREAD_RESULT(
result);
391 result = pthread_condattr_destroy(&cond_attr);
392 VALIDATE_PTHREAD_RESULT(
result);
406 int result = pthread_mutex_destroy(data_.mutex());
407 VALIDATE_PTHREAD_RESULT(
result);
409 result = pthread_cond_destroy(data_.cond());
410 VALIDATE_PTHREAD_RESULT(
result);
413bool Monitor::TryEnter() {
414 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
416 int result = pthread_mutex_trylock(data_.mutex());
421 ASSERT_PTHREAD_SUCCESS(
result);
430void Monitor::Enter() {
431 DEBUG_ASSERT(!ThreadInterruptScope::in_thread_interrupt_scope());
433 int result = pthread_mutex_lock(data_.mutex());
434 VALIDATE_PTHREAD_RESULT(
result);
443void Monitor::Exit() {
450 int result = pthread_mutex_unlock(data_.mutex());
451 VALIDATE_PTHREAD_RESULT(
result);
470 int result = pthread_cond_wait(data_.cond(), data_.mutex());
471 VALIDATE_PTHREAD_RESULT(
result);
474 ComputeTimeSpecMicros(&ts, micros);
475 int result = pthread_cond_timedwait(data_.cond(), data_.mutex(), &ts);
477 if (
result == ETIMEDOUT) {
486 ASSERT(owner_ == saved_owner);
491void Monitor::Notify() {
494 int result = pthread_cond_signal(data_.cond());
495 VALIDATE_PTHREAD_RESULT(
result);
498void Monitor::NotifyAll() {
501 int result = pthread_cond_broadcast(data_.cond());
502 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
const uint8_t uint32_t uint32_t GError ** error
Dart_NativeFunction function
constexpr intptr_t kMicrosecondsPerMillisecond
constexpr intptr_t kNanosecondsPerMicrosecond
void * malloc(size_t size)
constexpr intptr_t kNanosecondsPerSecond
void(* ThreadDestructor)(void *parameter)
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 JSON encoded network policy per domain This overrides the DisallowInsecureConnections switch Embedder can specify whether to allow or disallow insecure connections at a domain level old gen heap size
#define NO_SANITIZE_SAFE_STACK