mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-04-01 12:03:08 +00:00
Bug 956899 - Add a platform agnostic std::mutex work-alike; r=froydnj
This commit is contained in:
parent
bd531e5bce
commit
5f4e469c58
@ -83,6 +83,7 @@ UNIFIED_SOURCES += [
|
||||
'testStructuredClone.cpp',
|
||||
'testSymbol.cpp',
|
||||
'testThreadingExclusiveData.cpp',
|
||||
'testThreadingMutex.cpp',
|
||||
'testToIntWidth.cpp',
|
||||
'testTypedArrays.cpp',
|
||||
'testUbiNode.cpp',
|
||||
|
18
js/src/jsapi-tests/testThreadingMutex.cpp
Normal file
18
js/src/jsapi-tests/testThreadingMutex.cpp
Normal file
@ -0,0 +1,18 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
*/
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "jsapi-tests/tests.h"
|
||||
#include "threading/Mutex.h"
|
||||
|
||||
BEGIN_TEST(testThreadingMutex)
|
||||
{
|
||||
js::Mutex mutex;
|
||||
mutex.lock();
|
||||
mutex.unlock();
|
||||
return true;
|
||||
}
|
||||
END_TEST(testThreadingMutex)
|
@ -543,12 +543,14 @@ elif CONFIG['JS_CODEGEN_MIPS32'] or CONFIG['JS_CODEGEN_MIPS64']:
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
SOURCES += [
|
||||
'jit/ExecutableAllocatorWin.cpp',
|
||||
'threading/windows/Mutex.cpp',
|
||||
]
|
||||
# _CRT_RAND_S must be #defined before #including stdlib.h to get rand_s()
|
||||
DEFINES['_CRT_RAND_S'] = True
|
||||
else:
|
||||
SOURCES += [
|
||||
'jit/ExecutableAllocatorPosix.cpp',
|
||||
'threading/posix/Mutex.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['JS_HAS_CTYPES']:
|
||||
|
51
js/src/threading/Mutex.h
Normal file
51
js/src/threading/Mutex.h
Normal file
@ -0,0 +1,51 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef threading_Mutex_h
|
||||
#define threading_Mutex_h
|
||||
|
||||
#include "mozilla/Attributes.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
class Mutex
|
||||
{
|
||||
public:
|
||||
struct PlatformData;
|
||||
|
||||
Mutex();
|
||||
~Mutex();
|
||||
|
||||
void lock();
|
||||
void unlock();
|
||||
|
||||
private:
|
||||
Mutex(const Mutex&) = delete;
|
||||
void operator=(const Mutex&) = delete;
|
||||
Mutex(Mutex&&) = delete;
|
||||
void operator=(Mutex&&) = delete;
|
||||
|
||||
PlatformData* platformData();
|
||||
|
||||
// Linux and maybe other platforms define the storage size of pthread_mutex_t in
|
||||
// bytes. However, we must define it as an array of void pointers to ensure
|
||||
// proper alignment.
|
||||
#if defined(__APPLE__) && defined(__MACH__) && defined(__i386__)
|
||||
void* platformData_[11];
|
||||
#elif defined(__APPLE__) && defined(__MACH__) && defined(__amd64__)
|
||||
void* platformData_[8];
|
||||
#elif defined(__linux__)
|
||||
void* platformData_[40 / sizeof(void*)];
|
||||
#elif defined(_WIN32)
|
||||
void* platformData_[6];
|
||||
#else
|
||||
#error "Mutex platform data size isn't known for this platform"
|
||||
#endif
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // threading_Mutex_h
|
46
js/src/threading/posix/Mutex.cpp
Normal file
46
js/src/threading/posix/Mutex.cpp
Normal file
@ -0,0 +1,46 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "threading/Mutex.h"
|
||||
#include "threading/posix/MutexPlatformData.h"
|
||||
|
||||
js::Mutex::Mutex()
|
||||
{
|
||||
int r = pthread_mutex_init(&platformData()->ptMutex, NULL);
|
||||
MOZ_RELEASE_ASSERT(r == 0);
|
||||
}
|
||||
|
||||
js::Mutex::~Mutex()
|
||||
{
|
||||
int r = pthread_mutex_destroy(&platformData()->ptMutex);
|
||||
MOZ_RELEASE_ASSERT(r == 0);
|
||||
}
|
||||
|
||||
void
|
||||
js::Mutex::lock()
|
||||
{
|
||||
int r = pthread_mutex_lock(&platformData()->ptMutex);
|
||||
MOZ_RELEASE_ASSERT(r == 0);
|
||||
}
|
||||
|
||||
void
|
||||
js::Mutex::unlock()
|
||||
{
|
||||
int r = pthread_mutex_unlock(&platformData()->ptMutex);
|
||||
MOZ_RELEASE_ASSERT(r == 0);
|
||||
}
|
||||
|
||||
js::Mutex::PlatformData*
|
||||
js::Mutex::platformData()
|
||||
{
|
||||
static_assert(sizeof(platformData_) >= sizeof(PlatformData),
|
||||
"platformData_ is too small");
|
||||
return reinterpret_cast<PlatformData*>(platformData_);
|
||||
}
|
23
js/src/threading/posix/MutexPlatformData.h
Normal file
23
js/src/threading/posix/MutexPlatformData.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* vim: set ts=8 sts=4 et sw=4 tw=99:
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef platform_win_MutexPlatformData_h
|
||||
#define platform_win_MutexPlatformData_h
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#include "threading/Mutex.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
struct Mutex::PlatformData
|
||||
{
|
||||
pthread_mutex_t ptMutex;
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // platform_win_MutexPlatformData_h
|
83
js/src/threading/windows/Mutex.cpp
Normal file
83
js/src/threading/windows/Mutex.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Assertions.h"
|
||||
#include "mozilla/DebugOnly.h"
|
||||
|
||||
#include "jswin.h"
|
||||
|
||||
#include "threading/Mutex.h"
|
||||
#include "threading/windows/MutexPlatformData.h"
|
||||
|
||||
namespace {
|
||||
|
||||
// We build with a toolkit that supports WinXP, so we have to probe
|
||||
// for modern features at runtime. This is necessary because Vista and
|
||||
// later automatically allocate and subsequently leak a debug info
|
||||
// object for each critical section that we allocate unless we tell it
|
||||
// not to. In order to tell it not to, we need the extra flags field
|
||||
// provided by the Ex version of InitializeCriticalSection.
|
||||
struct MutexNativeImports
|
||||
{
|
||||
using InitializeCriticalSectionExT = BOOL (WINAPI*)(CRITICAL_SECTION*, DWORD, DWORD);
|
||||
InitializeCriticalSectionExT InitializeCriticalSectionEx;
|
||||
|
||||
MutexNativeImports() {
|
||||
HMODULE kernel32_dll = GetModuleHandle("kernel32.dll");
|
||||
MOZ_RELEASE_ASSERT(kernel32_dll != NULL);
|
||||
InitializeCriticalSectionEx = reinterpret_cast<InitializeCriticalSectionExT>(
|
||||
GetProcAddress(kernel32_dll, "InitializeCriticalSectionEx"));
|
||||
}
|
||||
|
||||
bool hasInitializeCriticalSectionEx() const {
|
||||
return InitializeCriticalSectionEx;
|
||||
}
|
||||
};
|
||||
|
||||
static MutexNativeImports NativeImports;
|
||||
|
||||
} // (anonymous namespace)
|
||||
|
||||
js::Mutex::Mutex()
|
||||
{
|
||||
// This number was adopted from NSPR.
|
||||
const static DWORD LockSpinCount = 1500;
|
||||
BOOL r;
|
||||
if (NativeImports.hasInitializeCriticalSectionEx()) {
|
||||
r = NativeImports.InitializeCriticalSectionEx(&platformData()->criticalSection,
|
||||
LockSpinCount,
|
||||
CRITICAL_SECTION_NO_DEBUG_INFO);
|
||||
} else {
|
||||
r = InitializeCriticalSectionAndSpinCount(&platformData()->criticalSection,
|
||||
LockSpinCount);
|
||||
}
|
||||
MOZ_RELEASE_ASSERT(r);
|
||||
}
|
||||
|
||||
js::Mutex::~Mutex()
|
||||
{
|
||||
DeleteCriticalSection(&platformData()->criticalSection);
|
||||
}
|
||||
|
||||
void
|
||||
js::Mutex::lock()
|
||||
{
|
||||
EnterCriticalSection(&platformData()->criticalSection);
|
||||
}
|
||||
|
||||
void
|
||||
js::Mutex::unlock()
|
||||
{
|
||||
LeaveCriticalSection(&platformData()->criticalSection);
|
||||
}
|
||||
|
||||
js::Mutex::PlatformData*
|
||||
js::Mutex::platformData()
|
||||
{
|
||||
static_assert(sizeof(platformData_) >= sizeof(PlatformData),
|
||||
"platformData_ is too small");
|
||||
return reinterpret_cast<PlatformData*>(platformData_);
|
||||
}
|
23
js/src/threading/windows/MutexPlatformData.h
Normal file
23
js/src/threading/windows/MutexPlatformData.h
Normal file
@ -0,0 +1,23 @@
|
||||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef platform_win_MutexPlatformData_h
|
||||
#define platform_win_MutexPlatformData_h
|
||||
|
||||
#include "jswin.h"
|
||||
|
||||
#include "threading/Mutex.h"
|
||||
|
||||
namespace js {
|
||||
|
||||
struct Mutex::PlatformData
|
||||
{
|
||||
CRITICAL_SECTION criticalSection;
|
||||
};
|
||||
|
||||
} // namespace js
|
||||
|
||||
#endif // platform_win_MutexPlatformData_h
|
Loading…
x
Reference in New Issue
Block a user