Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(731)

Unified Diff: Source/core/dom/LockManager.cpp

Issue 148283013: Blink JavaScript shared memory prototype. Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Tweaks Created 6 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « Source/core/dom/LockManager.h ('k') | Source/core/dom/LockManager.idl » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/core/dom/LockManager.cpp
diff --git a/Source/core/dom/LockManager.cpp b/Source/core/dom/LockManager.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ef1b30bb96a76bd11422d820ce77b51db1f7f19c
--- /dev/null
+++ b/Source/core/dom/LockManager.cpp
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2014 Google Inc. All Rights Reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#include "config.h"
+#include "core/dom/LockManager.h"
+
+#include "core/dom/ExecutionContext.h"
+
+namespace WebCore {
+
+static inline uint32_t murmurHash3Finalize(uint32_t h)
+{
+ h ^= h >> 16;
+ h *= 0x85ebca6b;
+ h ^= h >> 13;
+ h *= 0xc2b2ae35;
+ h ^= h >> 16;
+ return h;
+}
+
+static inline void getIndexes(uint32_t uid, uint32_t *shard, uint32_t *lock)
+{
+ uint32_t hash = murmurHash3Finalize(uid);
+ *shard = hash & SHARD_MASK;
+ *lock = hash >> SHARD_BITS;
+}
+
+class LockInfo {
+public:
+ LockInfo();
+ bool locked;
+ ThreadCondition cond;
+ uint32_t holdCount;
+};
+
+LockInfo::LockInfo()
+ : locked(false)
+ , holdCount(0)
+{
+}
+
+LockShard::~LockShard()
+{
+ // printf("destroying shard %p\n", this);
+ LockHashMap::iterator iter;
+ for (iter = locks.begin(); iter != locks.end(); ++iter) {
+ delete iter->value;
+ }
+ locks.clear();
+}
+
+LockInfo* LockShard::get(uint32_t uid)
+{
+ LockHashMap::iterator iter = locks.find(uid);
+ if (iter != locks.end()) {
+ return iter->value;
+ }
+ LockInfo* info = new LockInfo();
+ locks.add(uid, info);
+ return info;
+}
+
+void LockManagerImpl::lock(uint32_t uid)
+{
+ uint32_t shardID;
+ uint32_t lock;
+ getIndexes(uid, &shardID, &lock);
+ LockShard& shard = shards[shardID];
+ shard.mutex.lock();
+ LockInfo* info = shard.get(lock);
+ // printf("enter %u %u %u\n", uid, shardID, lock);
+ info->holdCount += 1;
+ if (info->holdCount != 1) {
+ info->cond.wait(shard.mutex);
+ }
+ // printf("lock %u %u %u\n", uid, shardID, lock);
+ shard.mutex.unlock();
+}
+
+void LockManagerImpl::unlock(uint32_t uid)
+{
+ uint32_t shardID;
+ uint32_t lock;
+ getIndexes(uid, &shardID, &lock);
+ LockShard& shard = shards[shardID];
+ shard.mutex.lock();
+ LockInfo* info = shard.get(lock);
+ info->holdCount -= 1;
+ if (info->holdCount) {
+ info->cond.signal();
+ }
+ // printf("unlock %u %u %u\n", uid, shardID, lock);
+ shard.mutex.unlock();
+}
+
+// Store the impl in a singleton to avoid the need to transfer the lock manager.
+// This is an awful hack to speed up prototyping.
+class LockManagerHack {
+public:
+ ~LockManagerHack()
+ {
+ }
+ PassRefPtr<LockManagerImpl> get()
+ {
+ MutexLocker lock(m);
+ if (!impl) {
+ impl = adoptRef(new LockManagerImpl());
+ }
+ return impl;
+ }
+private:
+ Mutex m;
+ RefPtr<LockManagerImpl> impl;
+};
+
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wglobal-constructors"
+#pragma clang diagnostic ignored "-Wexit-time-destructors"
+static LockManagerHack hack;
+#pragma clang diagnostic pop
+
+LockManager::LockManager(ExecutionContext*)
+: impl(hack.get())
+{
+}
+
+void LockManager::lock(unsigned long uid)
+{
+ impl->lock(uid);
+}
+
+void LockManager::unlock(unsigned long uid)
+{
+ impl->unlock(uid);
+}
+
+void LockManager::nop()
+{
+}
+
+} // namespace WebCore
« no previous file with comments | « Source/core/dom/LockManager.h ('k') | Source/core/dom/LockManager.idl » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698