Changeset: 3207bb2df5e9 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/3207bb2df5e9
Modified Files:
gdk/gdk_hash.c
gdk/gdk_system.h
Branch: default
Log Message:
Don't wait for ever for a write lock, but test in a loop.
diffs (63 lines):
diff --git a/gdk/gdk_hash.c b/gdk/gdk_hash.c
--- a/gdk/gdk_hash.c
+++ b/gdk/gdk_hash.c
@@ -990,7 +990,29 @@ BAThash(BAT *b)
if (BATcheckhash(b)) {
return GDK_SUCCEED;
}
- MT_rwlock_wrlock(&b->thashlock);
+ for (;;) {
+ /* If multiple threads simultaneously try to build a
+ * hash on a bat, e.g. in order to perform a join, it
+ * may happen that one thread succeeds in obtaining the
+ * write lock, then builds the hash, releases the lock,
+ * acquires the read lock, and performs the join. The
+ * other threads may then still be attempting to acquire
+ * the write lock. But now they have to wait until the
+ * read lock is released, which can be quite a long
+ * time. Especially if a second thread goes through the
+ * same process as the first. */
+ if (MT_rwlock_wrtry(&b->thashlock))
+ break;
+ MT_sleep_ms(1);
+ if (MT_rwlock_rdtry(&b->thashlock)) {
+ if (b->thash != NULL && b->thash != (Hash *) 1) {
+ MT_rwlock_rdunlock(&b->thashlock);
+ return GDK_SUCCEED;
+ }
+ MT_rwlock_rdunlock(&b->thashlock);
+ }
+ }
+ /* we have the write lock */
if (b->thash == NULL) {
struct canditer ci;
canditer_init(&ci, b, NULL);
diff --git a/gdk/gdk_system.h b/gdk/gdk_system.h
--- a/gdk/gdk_system.h
+++ b/gdk/gdk_system.h
@@ -370,10 +370,12 @@ typedef struct MT_RWLock {
#define MT_rwlock_destroy(l) ((void) 0)
#define MT_rwlock_rdlock(l) AcquireSRWLockShared(&(l)->lock)
+#define MT_rwlock_rdtry(l) TryAcquireSRWLockShared(&(l)->lock)
#define MT_rwlock_rdunlock(l) ReleaseSRWLockShared(&(l)->lock)
#define MT_rwlock_wrlock(l) AcquireSRWLockExclusive(&(l)->lock)
+#define MT_rwlock_wrtry(l) TryAcquireSRWLockExclusive(&(l)->lock)
#define MT_rwlock_wrunlock(l) ReleaseSRWLockExclusive(&(l)->lock)
@@ -455,10 +457,12 @@ typedef struct MT_RWLock {
#define MT_rwlock_destroy(l) pthread_rwlock_destroy(&(l)->lock)
#define MT_rwlock_rdlock(l) pthread_rwlock_rdlock(&(l)->lock)
+#define MT_rwlock_rdtry(l) (pthread_rwlock_tryrdlock(&(l)->lock) == 0)
#define MT_rwlock_rdunlock(l) pthread_rwlock_unlock(&(l)->lock)
#define MT_rwlock_wrlock(l) pthread_rwlock_wrlock(&(l)->lock)
+#define MT_rwlock_wrtry(l) (pthread_rwlock_trywrlock(&(l)->lock) == 0)
#define MT_rwlock_wrunlock(l) pthread_rwlock_unlock(&(l)->lock)
_______________________________________________
checkin-list mailing list
[email protected]
https://www.monetdb.org/mailman/listinfo/checkin-list