aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Mike Klein <mtklein@chromium.org>2017-10-30 11:57:15 -0400
committerGravatar Skia Commit-Bot <skia-commit-bot@chromium.org>2017-10-30 16:45:29 +0000
commit03141d25cf75c4ce6cdb94f90e9538ee3c878699 (patch)
treed635693f932ac01306c0bda8b388911a1f79199b
parentcc309eb9b18a707dfb94d89866a474bebf7f2777 (diff)
remove SkThread, using std::thread instead
Change-Id: I871dd5eea4496e87c206b46d9eae81cb521b11ce Reviewed-on: https://skia-review.googlesource.com/65103 Reviewed-by: Hal Canary <halcanary@google.com> Commit-Queue: Mike Klein <mtklein@chromium.org>
-rw-r--r--BUILD.gn2
-rw-r--r--bench/nanobench.cpp27
-rw-r--r--dm/DM.cpp1
-rw-r--r--gn/utils.gni3
-rw-r--r--public.bzl1
-rw-r--r--src/core/SkExecutor.cpp15
-rw-r--r--src/utils/SkThreadUtils.h39
-rw-r--r--src/utils/SkThreadUtils_pthread.cpp116
-rw-r--r--src/utils/SkThreadUtils_pthread.h43
-rw-r--r--src/utils/SkThreadUtils_win.cpp100
-rw-r--r--src/utils/SkThreadUtils_win.h27
-rw-r--r--tests/RefCntTest.cpp22
-rw-r--r--tests/StringTest.cpp27
-rw-r--r--tests/TLSTest.cpp51
14 files changed, 65 insertions, 409 deletions
diff --git a/BUILD.gn b/BUILD.gn
index 03a11a6d75..a0c8973312 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -798,8 +798,6 @@ component("skia") {
} else {
sources += [ "src/ports/SkFontMgr_win_dw_factory.cpp" ]
}
- sources -=
- [ get_path_info("src/utils/SkThreadUtils_pthread.cpp", "abspath") ]
libs += [
"FontSub.lib",
"Ole32.lib",
diff --git a/bench/nanobench.cpp b/bench/nanobench.cpp
index c5dfe0cf7f..550e0b7744 100644
--- a/bench/nanobench.cpp
+++ b/bench/nanobench.cpp
@@ -45,13 +45,13 @@
#include "SkString.h"
#include "SkSurface.h"
#include "SkTaskGroup.h"
-#include "SkThreadUtils.h"
#include "SkTraceEvent.h"
#include "Stats.h"
#include "ThermalManager.h"
#include "ios_utils.h"
#include <stdlib.h>
+#include <thread>
extern bool gSkForceRasterPipelineBlitter;
@@ -1109,21 +1109,18 @@ private:
// Some runs (mostly, Valgrind) are so slow that the bot framework thinks we've hung.
// This prints something every once in a while so that it knows we're still working.
static void start_keepalive() {
- struct Loop {
- static void forever(void*) {
- for (;;) {
- static const int kSec = 1200;
- #if defined(SK_BUILD_FOR_WIN)
- Sleep(kSec * 1000);
- #else
- sleep(kSec);
- #endif
- SkDebugf("\nBenchmarks still running...\n");
- }
+ static std::thread* intentionallyLeaked = new std::thread([]{
+ for (;;) {
+ static const int kSec = 1200;
+ #if defined(SK_BUILD_FOR_WIN)
+ Sleep(kSec * 1000);
+ #else
+ sleep(kSec);
+ #endif
+ SkDebugf("\nBenchmarks still running...\n");
}
- };
- static SkThread* intentionallyLeaked = new SkThread(Loop::forever);
- intentionallyLeaked->start();
+ });
+ (void)intentionallyLeaked;
}
int main(int argc, char** argv) {
diff --git a/dm/DM.cpp b/dm/DM.cpp
index 00bcf6ab33..b43ce6f60d 100644
--- a/dm/DM.cpp
+++ b/dm/DM.cpp
@@ -38,7 +38,6 @@
#include "SkSpinlock.h"
#include "SkTHash.h"
#include "SkTaskGroup.h"
-#include "SkThreadUtils.h"
#include "Test.h"
#include "Timer.h"
#include "ios_utils.h"
diff --git a/gn/utils.gni b/gn/utils.gni
index 54e7f4443d..8bcf4ee7d1 100644
--- a/gn/utils.gni
+++ b/gn/utils.gni
@@ -62,11 +62,8 @@ skia_utils_sources = [
"$_src/utils/SkShadowTessellator.h",
"$_src/utils/SkShadowUtils.cpp",
"$_src/utils/SkTextBox.cpp",
- "$_src/utils/SkThreadUtils.h",
"$_src/utils/SkThreadUtils_pthread.cpp",
- "$_src/utils/SkThreadUtils_pthread.h",
"$_src/utils/SkThreadUtils_win.cpp",
- "$_src/utils/SkThreadUtils_win.h",
"$_src/utils/SkWhitelistTypefaces.cpp",
#mac
diff --git a/public.bzl b/public.bzl
index d66781b534..3cd08fee6a 100644
--- a/public.bzl
+++ b/public.bzl
@@ -225,7 +225,6 @@ BASE_SRCS_ALL = struct(
"src/ports/**/*",
"src/utils/android/**/*",
"src/utils/mac/**/*",
- "src/utils/SkThreadUtils_win.cpp", # Windows-only. Move to ports?
"src/utils/win/**/*",
"src/views/sdl/*",
"src/views/win/*",
diff --git a/src/core/SkExecutor.cpp b/src/core/SkExecutor.cpp
index d37431eabb..eb0412a55e 100644
--- a/src/core/SkExecutor.cpp
+++ b/src/core/SkExecutor.cpp
@@ -11,8 +11,8 @@
#include "SkSemaphore.h"
#include "SkSpinlock.h"
#include "SkTArray.h"
-#include "SkThreadUtils.h"
#include <deque>
+#include <thread>
#if defined(SK_BUILD_FOR_WIN32)
#include <windows.h>
@@ -65,8 +65,7 @@ class SkThreadPool final : public SkExecutor {
public:
explicit SkThreadPool(int threads) {
for (int i = 0; i < threads; i++) {
- fThreads.emplace_back(new SkThread(&Loop, this));
- fThreads.back()->start();
+ fThreads.emplace_back(&Loop, this);
}
}
@@ -77,7 +76,7 @@ public:
}
// Wait for each thread to shut down.
for (int i = 0; i < fThreads.count(); i++) {
- fThreads[i]->join();
+ fThreads[i].join();
}
}
@@ -126,10 +125,10 @@ private:
// Both SkMutex and SkSpinlock can work here.
using Lock = SkMutex;
- SkTArray<std::unique_ptr<SkThread>> fThreads;
- WorkList fWork;
- Lock fWorkLock;
- SkSemaphore fWorkAvailable;
+ SkTArray<std::thread> fThreads;
+ WorkList fWork;
+ Lock fWorkLock;
+ SkSemaphore fWorkAvailable;
};
std::unique_ptr<SkExecutor> SkExecutor::MakeFIFOThreadPool(int threads) {
diff --git a/src/utils/SkThreadUtils.h b/src/utils/SkThreadUtils.h
deleted file mode 100644
index d9fc99d397..0000000000
--- a/src/utils/SkThreadUtils.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkThreadUtils_DEFINED
-#define SkThreadUtils_DEFINED
-
-#include "SkTypes.h"
-
-class SkThread : SkNoncopyable {
-public:
- typedef void (*entryPointProc)(void*);
-
- SkThread(entryPointProc entryPoint, void* data = nullptr);
-
- /**
- * Non-virtual, do not subclass.
- */
- ~SkThread();
-
- /**
- * Starts the thread. Returns false if the thread could not be started.
- */
- bool start();
-
- /**
- * Waits for the thread to finish.
- * If the thread has not started, returns immediately.
- */
- void join();
-
-private:
- void* fData;
-};
-
-#endif
diff --git a/src/utils/SkThreadUtils_pthread.cpp b/src/utils/SkThreadUtils_pthread.cpp
index 0bd804d43a..ae4db9ae55 100644
--- a/src/utils/SkThreadUtils_pthread.cpp
+++ b/src/utils/SkThreadUtils_pthread.cpp
@@ -1,117 +1,11 @@
/*
- * Copyright 2012 Google Inc.
+ * Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-#include "SkTypes.h"
-
-#include "SkThreadUtils.h"
-#include "SkThreadUtils_pthread.h"
-
-#include <pthread.h>
-#include <signal.h>
-
-PThreadEvent::PThreadEvent() : fConditionFlag(false) {
- pthread_cond_init(&fCondition, nullptr);
- pthread_mutex_init(&fConditionMutex, nullptr);
-}
-PThreadEvent::~PThreadEvent() {
- pthread_mutex_destroy(&fConditionMutex);
- pthread_cond_destroy(&fCondition);
-}
-void PThreadEvent::trigger() {
- pthread_mutex_lock(&fConditionMutex);
- fConditionFlag = true;
- pthread_cond_signal(&fCondition);
- pthread_mutex_unlock(&fConditionMutex);
-}
-void PThreadEvent::wait() {
- pthread_mutex_lock(&fConditionMutex);
- while (!fConditionFlag) {
- pthread_cond_wait(&fCondition, &fConditionMutex);
- }
- pthread_mutex_unlock(&fConditionMutex);
-}
-bool PThreadEvent::isTriggered() {
- bool currentFlag;
- pthread_mutex_lock(&fConditionMutex);
- currentFlag = fConditionFlag;
- pthread_mutex_unlock(&fConditionMutex);
- return currentFlag;
-}
-
-SkThread_PThreadData::SkThread_PThreadData(SkThread::entryPointProc entryPoint, void* data)
- : fPThread()
- , fValidPThread(false)
- , fParam(data)
- , fEntryPoint(entryPoint)
-{
- pthread_attr_init(&fAttr);
- pthread_attr_setdetachstate(&fAttr, PTHREAD_CREATE_JOINABLE);
-}
-
-SkThread_PThreadData::~SkThread_PThreadData() {
- pthread_attr_destroy(&fAttr);
-}
-
-static void* thread_start(void* arg) {
- SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(arg);
- // Wait for start signal
- pthreadData->fStarted.wait();
-
- // Call entry point only if thread was not canceled before starting.
- if (!pthreadData->fCanceled.isTriggered()) {
- pthreadData->fEntryPoint(pthreadData->fParam);
- }
- return nullptr;
-}
-
-SkThread::SkThread(entryPointProc entryPoint, void* data) {
- SkThread_PThreadData* pthreadData = new SkThread_PThreadData(entryPoint, data);
- fData = pthreadData;
-
- int ret = pthread_create(&(pthreadData->fPThread),
- &(pthreadData->fAttr),
- thread_start,
- pthreadData);
-
- pthreadData->fValidPThread = (0 == ret);
-}
-
-SkThread::~SkThread() {
- if (fData != nullptr) {
- SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData);
- // If created thread but start was never called, kill the thread.
- if (pthreadData->fValidPThread && !pthreadData->fStarted.isTriggered()) {
- pthreadData->fCanceled.trigger();
- if (this->start()) {
- this->join();
- }
- }
- delete pthreadData;
- }
-}
-
-bool SkThread::start() {
- SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData);
- if (!pthreadData->fValidPThread) {
- return false;
- }
-
- if (pthreadData->fStarted.isTriggered()) {
- return false;
- }
- pthreadData->fStarted.trigger();
- return true;
-}
-
-void SkThread::join() {
- SkThread_PThreadData* pthreadData = static_cast<SkThread_PThreadData*>(fData);
- if (!pthreadData->fValidPThread || !pthreadData->fStarted.isTriggered()) {
- return;
- }
-
- pthread_join(pthreadData->fPThread, nullptr);
-}
+// Nothing to see here.
+//
+// We just need to keep this file around until we do the song and dance
+// to stop explicitly removing it from Chromium's GN build.
diff --git a/src/utils/SkThreadUtils_pthread.h b/src/utils/SkThreadUtils_pthread.h
deleted file mode 100644
index 3e1020275c..0000000000
--- a/src/utils/SkThreadUtils_pthread.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkThreadUtils_PThreadData_DEFINED
-#define SkThreadUtils_PThreadData_DEFINED
-
-#include "SkThreadUtils.h"
-#include <pthread.h>
-
-class PThreadEvent : SkNoncopyable {
-public:
- PThreadEvent();
- ~PThreadEvent();
- void trigger();
- void wait();
- bool isTriggered();
-
-private:
- pthread_cond_t fCondition;
- pthread_mutex_t fConditionMutex;
- bool fConditionFlag;
-};
-
-class SkThread_PThreadData : SkNoncopyable {
-public:
- SkThread_PThreadData(SkThread::entryPointProc entryPoint, void* data);
- ~SkThread_PThreadData();
- pthread_t fPThread;
- bool fValidPThread;
- PThreadEvent fStarted;
- PThreadEvent fCanceled;
-
- pthread_attr_t fAttr;
-
- void* fParam;
- SkThread::entryPointProc fEntryPoint;
-};
-
-#endif
diff --git a/src/utils/SkThreadUtils_win.cpp b/src/utils/SkThreadUtils_win.cpp
index 0da339aa84..ae4db9ae55 100644
--- a/src/utils/SkThreadUtils_win.cpp
+++ b/src/utils/SkThreadUtils_win.cpp
@@ -1,101 +1,11 @@
/*
- * Copyright 2012 Google Inc.
+ * Copyright 2017 Google Inc.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
-#include "SkTypes.h"
-#if defined(SK_BUILD_FOR_WIN32)
-
-#include "SkThreadUtils.h"
-#include "SkThreadUtils_win.h"
-
-SkThread_WinData::SkThread_WinData(SkThread::entryPointProc entryPoint, void* data)
- : fHandle(nullptr)
- , fParam(data)
- , fThreadId(0)
- , fEntryPoint(entryPoint)
- , fStarted(false)
-{
- fCancelEvent = CreateEvent(
- nullptr, // default security attributes
- false, //auto reset
- false, //not signaled
- nullptr); //no name
-}
-
-SkThread_WinData::~SkThread_WinData() {
- CloseHandle(fCancelEvent);
-}
-
-static DWORD WINAPI thread_start(LPVOID data) {
- SkThread_WinData* winData = static_cast<SkThread_WinData*>(data);
-
- //See if this thread was canceled before starting.
- if (WaitForSingleObject(winData->fCancelEvent, 0) == WAIT_OBJECT_0) {
- return 0;
- }
-
- winData->fEntryPoint(winData->fParam);
- return 0;
-}
-
-SkThread::SkThread(entryPointProc entryPoint, void* data) {
- SkThread_WinData* winData = new SkThread_WinData(entryPoint, data);
- fData = winData;
-
- if (nullptr == winData->fCancelEvent) {
- return;
- }
-
- winData->fHandle = CreateThread(
- nullptr, // default security attributes
- 0, // use default stack size
- thread_start, // thread function name (proxy)
- winData, // argument to thread function (proxy args)
- CREATE_SUSPENDED, // we used to set processor affinity, which needed this
- &winData->fThreadId); // returns the thread identifier
-}
-
-SkThread::~SkThread() {
- if (fData != nullptr) {
- SkThread_WinData* winData = static_cast<SkThread_WinData*>(fData);
- // If created thread but start was never called, kill the thread.
- if (winData->fHandle != nullptr && !winData->fStarted) {
- if (SetEvent(winData->fCancelEvent) != 0) {
- if (this->start()) {
- this->join();
- }
- } else {
- //kill with prejudice
- TerminateThread(winData->fHandle, -1);
- }
- }
- delete winData;
- }
-}
-
-bool SkThread::start() {
- SkThread_WinData* winData = static_cast<SkThread_WinData*>(fData);
- if (nullptr == winData->fHandle) {
- return false;
- }
-
- if (winData->fStarted) {
- return false;
- }
- winData->fStarted = -1 != ResumeThread(winData->fHandle);
- return winData->fStarted;
-}
-
-void SkThread::join() {
- SkThread_WinData* winData = static_cast<SkThread_WinData*>(fData);
- if (nullptr == winData->fHandle || !winData->fStarted) {
- return;
- }
-
- WaitForSingleObject(winData->fHandle, INFINITE);
-}
-
-#endif//defined(SK_BUILD_FOR_WIN32)
+// Nothing to see here.
+//
+// We just need to keep this file around until we do the song and dance
+// to stop explicitly removing it from Chromium's GN build.
diff --git a/src/utils/SkThreadUtils_win.h b/src/utils/SkThreadUtils_win.h
deleted file mode 100644
index b1de4816cf..0000000000
--- a/src/utils/SkThreadUtils_win.h
+++ /dev/null
@@ -1,27 +0,0 @@
-/*
- * Copyright 2012 Google Inc.
- *
- * Use of this source code is governed by a BSD-style license that can be
- * found in the LICENSE file.
- */
-
-#ifndef SkThreadUtils_WinData_DEFINED
-#define SkThreadUtils_WinData_DEFINED
-
-#include "SkLeanWindows.h"
-#include "SkThreadUtils.h"
-
-class SkThread_WinData : SkNoncopyable {
-public:
- SkThread_WinData(SkThread::entryPointProc entryPoint, void* data);
- ~SkThread_WinData();
- HANDLE fHandle;
- HANDLE fCancelEvent;
-
- LPVOID fParam;
- DWORD fThreadId;
- SkThread::entryPointProc fEntryPoint;
- bool fStarted;
-};
-
-#endif
diff --git a/tests/RefCntTest.cpp b/tests/RefCntTest.cpp
index 4bad342cee..1a100b549c 100644
--- a/tests/RefCntTest.cpp
+++ b/tests/RefCntTest.cpp
@@ -6,10 +6,10 @@
*/
#include "SkRefCnt.h"
-#include "SkThreadUtils.h"
#include "SkTypes.h"
#include "SkWeakRefCnt.h"
#include "Test.h"
+#include <thread>
static void bounce_ref(void* data) {
SkRefCnt* ref = static_cast<SkRefCnt*>(data);
@@ -22,11 +22,8 @@ static void bounce_ref(void* data) {
static void test_refCnt(skiatest::Reporter* reporter) {
SkRefCnt* ref = new SkRefCnt();
- SkThread thing1(bounce_ref, ref);
- SkThread thing2(bounce_ref, ref);
-
- SkAssertResult(thing1.start());
- SkAssertResult(thing2.start());
+ std::thread thing1(bounce_ref, ref);
+ std::thread thing2(bounce_ref, ref);
thing1.join();
thing2.join();
@@ -55,15 +52,10 @@ static void bounce_weak_weak_ref(void* data) {
static void test_weakRefCnt(skiatest::Reporter* reporter) {
SkWeakRefCnt* ref = new SkWeakRefCnt();
- SkThread thing1(bounce_ref, ref);
- SkThread thing2(bounce_ref, ref);
- SkThread thing3(bounce_weak_ref, ref);
- SkThread thing4(bounce_weak_weak_ref, ref);
-
- SkAssertResult(thing1.start());
- SkAssertResult(thing2.start());
- SkAssertResult(thing3.start());
- SkAssertResult(thing4.start());
+ std::thread thing1(bounce_ref, ref);
+ std::thread thing2(bounce_ref, ref);
+ std::thread thing3(bounce_weak_ref, ref);
+ std::thread thing4(bounce_weak_weak_ref, ref);
thing1.join();
thing2.join();
diff --git a/tests/StringTest.cpp b/tests/StringTest.cpp
index 91ef009edd..166637fd65 100644
--- a/tests/StringTest.cpp
+++ b/tests/StringTest.cpp
@@ -8,8 +8,8 @@
#include <stdarg.h>
#include <stdio.h>
#include "SkString.h"
-#include "SkThreadUtils.h"
#include "Test.h"
+#include <thread>
// Windows vsnprintf doesn't 0-terminate safely), but is so far
// encapsulated in SkString that we can't test it directly.
@@ -291,23 +291,16 @@ DEF_TEST(String_SkStrSplit_All, r) {
// https://bugs.chromium.org/p/skia/issues/detail?id=7107
DEF_TEST(String_Threaded, r) {
- SkString gString("foo");
- SkThread::entryPointProc readString = [](void* context) -> void {
- SkString gStringCopy = *reinterpret_cast<SkString*>(context);
- bool equals_string = gStringCopy.equals("test");
- (void)equals_string;
- };
- SkThread threads[] = {
- {readString, &gString},
- {readString, &gString},
- {readString, &gString},
- {readString, &gString},
- {readString, &gString},
- };
- for (SkThread& thread : threads) {
- thread.start();
+ SkString str("foo");
+
+ std::thread threads[5];
+ for (auto& thread : threads) {
+ thread = std::thread([&] {
+ SkString copy = str;
+ (void)copy.equals("test");
+ });
}
- for (SkThread& thread : threads) {
+ for (auto& thread : threads) {
thread.join();
}
}
diff --git a/tests/TLSTest.cpp b/tests/TLSTest.cpp
index 2702d9c000..0fadd7ed9c 100644
--- a/tests/TLSTest.cpp
+++ b/tests/TLSTest.cpp
@@ -5,14 +5,14 @@
* found in the LICENSE file.
*/
-#include "SkAtomics.h"
#include "SkGraphics.h"
#include "SkPaint.h"
#include "SkTLS.h"
-#include "SkThreadUtils.h"
#include "Test.h"
+#include <atomic>
+#include <thread>
-static void thread_main(void*) {
+static void thread_main() {
SkGraphics::SetTLSFontCacheLimit(1 * 1024 * 1024);
const char text[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
@@ -31,41 +31,26 @@ static void thread_main(void*) {
}
}
-static void test_threads(SkThread::entryPointProc proc) {
- SkThread* threads[8];
- int N = SK_ARRAY_COUNT(threads);
- int i;
+template <typename Fn>
+static void test_threads(Fn fn) {
+ std::thread threads[8];
- for (i = 0; i < N; ++i) {
- threads[i] = new SkThread(proc);
+ for (auto& thread : threads) {
+ thread = std::thread(fn);
}
-
- for (i = 0; i < N; ++i) {
- threads[i]->start();
- }
-
- for (i = 0; i < N; ++i) {
- threads[i]->join();
- }
-
- for (i = 0; i < N; ++i) {
- delete threads[i];
+ for (auto& thread : threads) {
+ thread.join();
}
}
-static int32_t gCounter;
+static std::atomic<int> gCounter{0};
-static void* FakeCreateTLS() {
- sk_atomic_inc(&gCounter);
+static void* fake_create_TLS() {
+ gCounter++;
return nullptr;
}
-
-static void FakeDeleteTLS(void*) {
- sk_atomic_dec(&gCounter);
-}
-
-static void testTLSDestructor(void*) {
- SkTLS::Get(FakeCreateTLS, FakeDeleteTLS);
+static void fake_delete_TLS(void*) {
+ gCounter--;
}
DEF_TEST(TLS, reporter) {
@@ -76,6 +61,8 @@ DEF_TEST(TLS, reporter) {
// Test to ensure that at thread destruction, TLS destructors
// have been called.
- test_threads(&testTLSDestructor);
- REPORTER_ASSERT(reporter, 0 == gCounter);
+ test_threads([] {
+ SkTLS::Get(fake_create_TLS, fake_delete_TLS);
+ });
+ REPORTER_ASSERT(reporter, 0 == gCounter.load());
}