Refactor Mutex.hpp (#4594)
* Remove `LockGuard` in favour of `std::lock_guard` * Rename `SimpleMutex` to `SpinLock`
This commit is contained in:
committed by
Stanislav Erokhin
parent
a994b71d3f
commit
a41e1cb66b
@@ -65,7 +65,7 @@ public:
|
||||
for (auto& node : queue_) {
|
||||
node.owner_ = nullptr;
|
||||
}
|
||||
std::lock_guard<SimpleMutex> guard(owner_.mutex_);
|
||||
std::lock_guard<SpinLock> guard(owner_.mutex_);
|
||||
owner_.queue_.splice(owner_.queue_.end(), queue_);
|
||||
owner_.deletionQueue_.splice(owner_.deletionQueue_.end(), deletionQueue_);
|
||||
}
|
||||
@@ -108,7 +108,7 @@ public:
|
||||
explicit Iterable(MultiSourceQueue& owner) noexcept : owner_(owner), guard_(owner_.mutex_) {}
|
||||
|
||||
MultiSourceQueue& owner_; // weak
|
||||
std::unique_lock<SimpleMutex> guard_;
|
||||
std::unique_lock<SpinLock> guard_;
|
||||
};
|
||||
|
||||
// Lock `MultiSourceQueue` for safe iteration. If element was scheduled for deletion,
|
||||
@@ -117,7 +117,7 @@ public:
|
||||
|
||||
// Lock `MultiSourceQueue` and apply deletions. Only deletes elements that were published.
|
||||
void ApplyDeletions() noexcept {
|
||||
std::lock_guard<SimpleMutex> guard(mutex_);
|
||||
std::lock_guard<SpinLock> guard(mutex_);
|
||||
std::list<Node*> remainingDeletions;
|
||||
|
||||
auto it = deletionQueue_.begin();
|
||||
@@ -143,7 +143,7 @@ private:
|
||||
// which is important for GC mark phase.
|
||||
std::list<Node> queue_;
|
||||
std::list<Node*> deletionQueue_;
|
||||
SimpleMutex mutex_;
|
||||
SpinLock mutex_;
|
||||
};
|
||||
|
||||
} // namespace kotlin
|
||||
|
||||
@@ -18,41 +18,31 @@
|
||||
#define RUNTIME_MUTEX_H
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
#include "KAssert.h"
|
||||
#include "Utils.hpp"
|
||||
|
||||
class SimpleMutex {
|
||||
private:
|
||||
int32_t atomicInt = 0;
|
||||
namespace kotlin {
|
||||
|
||||
public:
|
||||
void lock() {
|
||||
while (!__sync_bool_compare_and_swap(&atomicInt, 0, 1)) {
|
||||
// TODO: yield.
|
||||
class SpinLock : private Pinned {
|
||||
public:
|
||||
void lock() noexcept {
|
||||
while (!__sync_bool_compare_and_swap(&atomicInt, 0, 1)) {
|
||||
// TODO: yield.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unlock() {
|
||||
if (!__sync_bool_compare_and_swap(&atomicInt, 1, 0)) {
|
||||
RuntimeAssert(false, "Unable to unlock");
|
||||
void unlock() noexcept {
|
||||
if (!__sync_bool_compare_and_swap(&atomicInt, 1, 0)) {
|
||||
RuntimeAssert(false, "Unable to unlock");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// TODO: Consider using `std::atomic_flag`.
|
||||
int32_t atomicInt = 0;
|
||||
};
|
||||
|
||||
// TODO: use std::lock_guard instead?
|
||||
template <class Mutex>
|
||||
class LockGuard : private kotlin::Pinned {
|
||||
public:
|
||||
explicit LockGuard(Mutex& mutex_) : mutex(mutex_) {
|
||||
mutex.lock();
|
||||
}
|
||||
|
||||
~LockGuard() {
|
||||
mutex.unlock();
|
||||
}
|
||||
|
||||
private:
|
||||
Mutex& mutex;
|
||||
};
|
||||
} // namespace kotlin
|
||||
|
||||
#endif // RUNTIME_MUTEX_H
|
||||
|
||||
@@ -21,6 +21,8 @@
|
||||
|
||||
#if KONAN_OBJC_INTEROP
|
||||
|
||||
#import <mutex>
|
||||
|
||||
#import <Foundation/NSObject.h>
|
||||
#import <Foundation/NSValue.h>
|
||||
#import <Foundation/NSString.h>
|
||||
@@ -959,7 +961,7 @@ static const TypeInfo* createTypeInfo(Class clazz, const TypeInfo* superType, co
|
||||
return result;
|
||||
}
|
||||
|
||||
static SimpleMutex typeInfoCreationMutex;
|
||||
static kotlin::SpinLock typeInfoCreationMutex;
|
||||
|
||||
static const TypeInfo* getOrCreateTypeInfo(Class clazz) {
|
||||
const TypeInfo* result = Kotlin_ObjCExport_getAssociatedTypeInfo(clazz);
|
||||
@@ -973,7 +975,7 @@ static const TypeInfo* getOrCreateTypeInfo(Class clazz) {
|
||||
theForeignObjCObjectTypeInfo :
|
||||
getOrCreateTypeInfo(superClass);
|
||||
|
||||
LockGuard<SimpleMutex> lockGuard(typeInfoCreationMutex);
|
||||
std::lock_guard<kotlin::SpinLock> lockGuard(typeInfoCreationMutex);
|
||||
|
||||
result = Kotlin_ObjCExport_getAssociatedTypeInfo(clazz); // double-checking.
|
||||
if (result == nullptr) {
|
||||
@@ -993,7 +995,7 @@ const TypeInfo* Kotlin_ObjCExport_createTypeInfoWithKotlinFieldsFrom(Class clazz
|
||||
return createTypeInfo(clazz, superType, fieldsInfo);
|
||||
}
|
||||
|
||||
static SimpleMutex classCreationMutex;
|
||||
static kotlin::SpinLock classCreationMutex;
|
||||
static int anonymousClassNextId = 0;
|
||||
|
||||
static void addVirtualAdapters(Class clazz, const ObjCTypeAdapter* typeAdapter) {
|
||||
@@ -1067,7 +1069,7 @@ static Class getOrCreateClass(const TypeInfo* typeInfo) {
|
||||
} else {
|
||||
Class superClass = getOrCreateClass(typeInfo->superType_);
|
||||
|
||||
LockGuard<SimpleMutex> lockGuard(classCreationMutex); // Note: non-recursive
|
||||
std::lock_guard<kotlin::SpinLock> lockGuard(classCreationMutex); // Note: non-recursive
|
||||
|
||||
result = typeInfo->writableInfo_->objCExport.objCClass; // double-checking.
|
||||
if (result == nullptr) {
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include <objc/message.h>
|
||||
#include <cstdio>
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
|
||||
#include "Memory.h"
|
||||
#include "MemorySharedRefs.hpp"
|
||||
@@ -240,7 +241,7 @@ static void AddMethods(Class clazz, const struct ObjCMethodDescription* methods,
|
||||
}
|
||||
}
|
||||
|
||||
static SimpleMutex classCreationMutex;
|
||||
static kotlin::SpinLock classCreationMutex;
|
||||
static int anonymousClassNextId = 0;
|
||||
|
||||
static Class allocateClass(const KotlinObjCClassInfo* info) {
|
||||
@@ -271,7 +272,7 @@ static Class allocateClass(const KotlinObjCClassInfo* info) {
|
||||
}
|
||||
|
||||
void* CreateKotlinObjCClass(const KotlinObjCClassInfo* info) {
|
||||
LockGuard<SimpleMutex> lockGuard(classCreationMutex);
|
||||
std::lock_guard<kotlin::SpinLock> lockGuard(classCreationMutex);
|
||||
|
||||
void* createdClass = *info->createdClass;
|
||||
if (createdClass != nullptr) {
|
||||
|
||||
@@ -17,7 +17,7 @@
|
||||
namespace kotlin {
|
||||
|
||||
// TODO: Consider different locking mechanisms.
|
||||
template <typename Value, typename Mutex = SimpleMutex>
|
||||
template <typename Value, typename Mutex = SpinLock>
|
||||
class SingleLockList : private Pinned {
|
||||
public:
|
||||
class Node : Pinned {
|
||||
@@ -71,7 +71,7 @@ public:
|
||||
Node* Emplace(Args... args) noexcept {
|
||||
auto* nodePtr = new Node(args...);
|
||||
std::unique_ptr<Node> node(nodePtr);
|
||||
LockGuard<Mutex> guard(mutex_);
|
||||
std::lock_guard<Mutex> guard(mutex_);
|
||||
if (root_) {
|
||||
root_->previous = node.get();
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public:
|
||||
|
||||
// Using `node` including its referred `Value` after `Erase` is undefined behaviour.
|
||||
void Erase(Node* node) noexcept {
|
||||
LockGuard<Mutex> guard(mutex_);
|
||||
std::lock_guard<Mutex> guard(mutex_);
|
||||
if (root_.get() == node) {
|
||||
root_ = std::move(node->next);
|
||||
if (root_) {
|
||||
|
||||
Reference in New Issue
Block a user