Flutter Engine
The Flutter Engine
thread_unittests.cc
Go to the documentation of this file.
1// Copyright 2013 The Flutter Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "flutter/fml/build_config.h"
6#include "flutter/fml/thread.h"
7
8#if defined(FML_OS_MACOSX) || defined(FML_OS_LINUX) || defined(FML_OS_ANDROID)
9#define FLUTTER_PTHREAD_SUPPORTED 1
10#else
11#define FLUTTER_PTHREAD_SUPPORTED 0
12#endif
13
14#if FLUTTER_PTHREAD_SUPPORTED
15#include <pthread.h>
16#else
17#endif
18
19#if defined(FML_OS_WIN)
20#include <windows.h>
21#endif
22
23#include <algorithm>
24#include <memory>
25#include "gtest/gtest.h"
26
27TEST(Thread, CanStartAndEnd) {
28 fml::Thread thread;
29 ASSERT_TRUE(thread.GetTaskRunner());
30}
31
32TEST(Thread, CanStartAndEndWithExplicitJoin) {
33 fml::Thread thread;
34 ASSERT_TRUE(thread.GetTaskRunner());
35 thread.Join();
36}
37
38TEST(Thread, HasARunningMessageLoop) {
39 fml::Thread thread;
40 bool done = false;
41 thread.GetTaskRunner()->PostTask([&done]() { done = true; });
42 thread.Join();
43 ASSERT_TRUE(done);
44}
45
46TEST(Thread, HasExpectedStackSize) {
47 size_t stack_size = 0;
48 fml::Thread thread;
49
50 thread.GetTaskRunner()->PostTask([&stack_size]() {
51#if defined(FML_OS_WIN)
52 ULONG_PTR low_limit;
53 ULONG_PTR high_limit;
54 GetCurrentThreadStackLimits(&low_limit, &high_limit);
55 stack_size = high_limit - low_limit;
56#elif defined(FML_OS_MACOSX)
57 stack_size = pthread_get_stacksize_np(pthread_self());
58#else
59 pthread_attr_t attr;
60 pthread_getattr_np(pthread_self(), &attr);
61 pthread_attr_getstacksize(&attr, &stack_size);
62 pthread_attr_destroy(&attr);
63#endif
64 });
65 thread.Join();
66
67 // Actual stack size will be aligned to page size, this assumes no supported
68 // platform has a page size larger than 16k. On Linux reducing the default
69 // stack size (8MB) does not seem to have any effect.
70 const size_t kPageSize = 16384;
71 ASSERT_TRUE(stack_size / kPageSize >=
73}
74
75#if FLUTTER_PTHREAD_SUPPORTED
76TEST(Thread, ThreadNameCreatedWithConfig) {
77 const std::string name = "Thread1";
78 fml::Thread thread(name);
79
80 bool done = false;
81 thread.GetTaskRunner()->PostTask([&done, &name]() {
82 done = true;
83 char thread_name[16];
84 pthread_t current_thread = pthread_self();
85 pthread_getname_np(current_thread, thread_name, 16);
86 ASSERT_EQ(thread_name, name);
87 });
88 thread.Join();
89 ASSERT_TRUE(done);
90}
91
92static int clamp_priority(int priority, int policy) {
93 return std::clamp(priority, sched_get_priority_min(policy),
94 sched_get_priority_max(policy));
95}
96
97static void MockThreadConfigSetter(const fml::Thread::ThreadConfig& config) {
98 // set thread name
100
101 pthread_t tid = pthread_self();
102 struct sched_param param;
103 int policy = SCHED_OTHER;
104 switch (config.priority) {
106 param.sched_priority = clamp_priority(10, policy);
107 break;
108 default:
109 param.sched_priority = clamp_priority(1, policy);
110 }
111 pthread_setschedparam(tid, policy, &param);
112}
113
114TEST(Thread, ThreadPriorityCreatedWithConfig) {
115 const std::string thread1_name = "Thread1";
116 const std::string thread2_name = "Thread2";
117
118 fml::Thread thread(MockThreadConfigSetter,
121 bool done = false;
122
123 struct sched_param param;
124 int policy;
125 thread.GetTaskRunner()->PostTask([&]() {
126 done = true;
127 char thread_name[16];
128 pthread_t current_thread = pthread_self();
129 pthread_getname_np(current_thread, thread_name, 16);
130 pthread_getschedparam(current_thread, &policy, &param);
131 ASSERT_EQ(thread_name, thread1_name);
132 ASSERT_EQ(policy, SCHED_OTHER);
133 ASSERT_EQ(param.sched_priority, clamp_priority(1, policy));
134 });
135
136 fml::Thread thread2(MockThreadConfigSetter,
139 thread2.GetTaskRunner()->PostTask([&]() {
140 done = true;
141 char thread_name[16];
142 pthread_t current_thread = pthread_self();
143 pthread_getname_np(current_thread, thread_name, 16);
144 pthread_getschedparam(current_thread, &policy, &param);
145 ASSERT_EQ(thread_name, thread2_name);
146 ASSERT_EQ(policy, SCHED_OTHER);
147 ASSERT_EQ(param.sched_priority, clamp_priority(10, policy));
148 });
149 thread.Join();
150 ASSERT_TRUE(done);
151}
152#endif // FLUTTER_PTHREAD_SUPPORTED
153
154#if defined(FML_OS_LINUX)
155TEST(Thread, LinuxLongThreadNameTruncated) {
156 const std::string name = "VeryLongThreadNameTest";
157 fml::Thread thread(name);
158
159 thread.GetTaskRunner()->PostTask([&name]() {
160 constexpr size_t kThreadNameLen = 16;
161 char thread_name[kThreadNameLen];
162 pthread_getname_np(pthread_self(), thread_name, kThreadNameLen);
163 ASSERT_EQ(thread_name, name.substr(0, kThreadNameLen - 1));
164 });
165 thread.Join();
166}
167#endif // FML_OS_LINUX
static void done(const char *config, const char *src, const char *srcOptions, const char *name)
Definition: DM.cpp:263
static unsigned clamp(SkFixed fx, int max)
virtual void PostTask(const fml::closure &task) override
Definition: task_runner.cc:24
void Join()
Definition: thread.cc:168
@ kNormal
Default priority level.
@ kDisplay
Suitable for threads which generate data for the display.
fml::RefPtr< fml::TaskRunner > GetTaskRunner() const
Definition: thread.cc:164
static size_t GetDefaultStackSize()
Definition: thread.cc:177
static void SetCurrentThreadName(const ThreadConfig &config)
Definition: thread.cc:135
DEF_SWITCHES_START aot vmservice shared library name
Definition: switches.h:32
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
Definition: switches.h:248
The ThreadConfig is the thread info include thread name, thread priority.
Definition: thread.h:35
ThreadPriority priority
Definition: thread.h:45
TEST(Thread, CanStartAndEnd)
__w64 unsigned long ULONG_PTR
Definition: windows_types.h:56