summaryrefslogtreecommitdiff
path: root/Source/WTF/wtf/Threading.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WTF/wtf/Threading.cpp')
-rw-r--r--Source/WTF/wtf/Threading.cpp145
1 files changed, 75 insertions, 70 deletions
diff --git a/Source/WTF/wtf/Threading.cpp b/Source/WTF/wtf/Threading.cpp
index 723a94ee4..c1dc35019 100644
--- a/Source/WTF/wtf/Threading.cpp
+++ b/Source/WTF/wtf/Threading.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2008, 2009 Apple Inc. All rights reserved.
+ * Copyright (C) 2008, 2009, 2014 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
@@ -25,33 +25,56 @@
#include "config.h"
#include "Threading.h"
-#include <wtf/OwnPtr.h>
-#include <wtf/PassOwnPtr.h>
-#include <string.h>
+#include <algorithm>
+#include <cmath>
+#include <cstring>
+#include <wtf/text/StringView.h>
+
+#if HAVE(QOS_CLASSES)
+#include <bmalloc/bmalloc.h>
+#endif
namespace WTF {
struct NewThreadContext {
WTF_MAKE_FAST_ALLOCATED;
public:
- NewThreadContext(ThreadFunction entryPoint, void* data, const char* name)
- : entryPoint(entryPoint)
- , data(data)
- , name(name)
- {
- }
-
- ThreadFunction entryPoint;
- void* data;
const char* name;
-
+ std::function<void()> entryPoint;
Mutex creationMutex;
};
+const char* normalizeThreadName(const char* threadName)
+{
+#if HAVE(PTHREAD_SETNAME_NP)
+ return threadName;
+#else
+ // This name can be com.apple.WebKit.ProcessLauncher or com.apple.CoreIPC.ReceiveQueue.
+ // We are using those names for the thread name, but both are longer than the limit of
+ // the platform thread name length, 32 for Windows and 16 for Linux.
+ StringView result(threadName);
+ size_t size = result.reverseFind('.');
+ if (size != notFound)
+ result = result.substring(size + 1);
+
+#if OS(WINDOWS)
+ constexpr const size_t kVisualStudioThreadNameLimit = 32 - 1;
+ if (result.length() > kVisualStudioThreadNameLimit)
+ result = result.right(kVisualStudioThreadNameLimit);
+#elif OS(LINUX)
+ constexpr const size_t kLinuxThreadNameLimit = 16 - 1;
+ if (result.length() > kLinuxThreadNameLimit)
+ result = result.right(kLinuxThreadNameLimit);
+#endif
+ ASSERT(result.characters8()[result.length()] == '\0');
+ return reinterpret_cast<const char*>(result.characters8());
+#endif
+}
+
static void threadEntryPoint(void* contextData)
{
- NewThreadContext* context = reinterpret_cast<NewThreadContext*>(contextData);
+ NewThreadContext* context = static_cast<NewThreadContext*>(contextData);
// Block until our creating thread has completed any extra setup work, including
// establishing ThreadIdentifier.
@@ -61,24 +84,17 @@ static void threadEntryPoint(void* contextData)
initializeCurrentThreadInternal(context->name);
- // Grab the info that we need out of the context, then deallocate it.
- ThreadFunction entryPoint = context->entryPoint;
- void* data = context->data;
+ auto entryPoint = WTFMove(context->entryPoint);
+
+ // Delete the context before starting the thread.
delete context;
- entryPoint(data);
+ entryPoint();
}
-ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
+ThreadIdentifier createThread(const char* name, std::function<void()> entryPoint)
{
- // Visual Studio has a 31-character limit on thread names. Longer names will
- // be truncated silently, but we'd like callers to know about the limit.
-#if !LOG_DISABLED && PLATFORM(WIN)
- if (name && strlen(name) > 31)
- LOG_ERROR("Thread name \"%s\" is longer than 31 characters and will be truncated by Visual Studio", name);
-#endif
-
- NewThreadContext* context = new NewThreadContext(entryPoint, data, name);
+ NewThreadContext* context = new NewThreadContext { name, WTFMove(entryPoint), { } };
// Prevent the thread body from executing until we've established the thread identifier.
MutexLocker locker(context->creationMutex);
@@ -86,60 +102,49 @@ ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char*
return createThreadInternal(threadEntryPoint, context, name);
}
-#if PLATFORM(MAC) || PLATFORM(WIN)
-
-// For ABI compatibility with Safari on Mac / Windows: Safari uses the private
-// createThread() and waitForThreadCompletion() functions directly and we need
-// to keep the old ABI compatibility until it's been rebuilt.
-
-typedef void* (*ThreadFunctionWithReturnValue)(void* argument);
-
-WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data, const char* name);
-
-struct ThreadFunctionWithReturnValueInvocation {
- ThreadFunctionWithReturnValueInvocation(ThreadFunctionWithReturnValue function, void* data)
- : function(function)
- , data(data)
- {
- }
-
- ThreadFunctionWithReturnValue function;
- void* data;
-};
-
-static void compatEntryPoint(void* param)
+ThreadIdentifier createThread(ThreadFunction entryPoint, void* data, const char* name)
{
- // Balanced by .release() in createThread.
- auto invocation = std::unique_ptr<ThreadFunctionWithReturnValueInvocation>(static_cast<ThreadFunctionWithReturnValueInvocation*>(param));
- invocation->function(invocation->data);
+ return createThread(name, [entryPoint, data] {
+ entryPoint(data);
+ });
}
-ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data, const char* name)
+void setCurrentThreadIsUserInteractive(int relativePriority)
{
- auto invocation = std::make_unique<ThreadFunctionWithReturnValueInvocation>(entryPoint, data);
-
- // Balanced by std::unique_ptr constructor in compatEntryPoint.
- return createThread(compatEntryPoint, invocation.release(), name);
+#if HAVE(QOS_CLASSES)
+ ASSERT(relativePriority <= 0);
+ ASSERT(relativePriority >= QOS_MIN_RELATIVE_PRIORITY);
+ pthread_set_qos_class_self_np(adjustedQOSClass(QOS_CLASS_USER_INTERACTIVE), relativePriority);
+#else
+ UNUSED_PARAM(relativePriority);
+#endif
}
-WTF_EXPORT_PRIVATE int waitForThreadCompletion(ThreadIdentifier, void**);
-
-int waitForThreadCompletion(ThreadIdentifier threadID, void**)
+void setCurrentThreadIsUserInitiated(int relativePriority)
{
- return waitForThreadCompletion(threadID);
+#if HAVE(QOS_CLASSES)
+ ASSERT(relativePriority <= 0);
+ ASSERT(relativePriority >= QOS_MIN_RELATIVE_PRIORITY);
+ pthread_set_qos_class_self_np(adjustedQOSClass(QOS_CLASS_USER_INITIATED), relativePriority);
+#else
+ UNUSED_PARAM(relativePriority);
+#endif
}
-// This function is deprecated but needs to be kept around for backward
-// compatibility. Use the 3-argument version of createThread above.
-
-WTF_EXPORT_PRIVATE ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data);
+#if HAVE(QOS_CLASSES)
+static qos_class_t globalMaxQOSclass { QOS_CLASS_UNSPECIFIED };
-ThreadIdentifier createThread(ThreadFunctionWithReturnValue entryPoint, void* data)
+void setGlobalMaxQOSClass(qos_class_t maxClass)
{
- auto invocation = std::make_unique<ThreadFunctionWithReturnValueInvocation>(entryPoint, data);
+ bmalloc::api::setScavengerThreadQOSClass(maxClass);
+ globalMaxQOSclass = maxClass;
+}
- // Balanced by adoptPtr() in compatEntryPoint.
- return createThread(compatEntryPoint, invocation.release(), 0);
+qos_class_t adjustedQOSClass(qos_class_t originalClass)
+{
+ if (globalMaxQOSclass != QOS_CLASS_UNSPECIFIED)
+ return std::min(originalClass, globalMaxQOSclass);
+ return originalClass;
}
#endif