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

Reply via email to