Changeset: f8a34ca7beb1 for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/f8a34ca7beb1
Modified Files:
        gdk/gdk_bbp.c
        gdk/gdk_utils.c
Branch: default
Log Message:

Fix lost wake-up problem.
A lost wake-up occurs when:
- a thread calls MT_cond_signal() of MT_cond_broadcast() (without lock);
- and another thread is between the test of the condition and the call
  to MT_cond_wait();
- and no threads are waiting.

We fix this by calling the broadcast while holding the lock.
An alternative fix would be to use a timeout in the wait, but that
requires calls to gettimeofday.


diffs (76 lines):

diff --git a/gdk/gdk_bbp.c b/gdk/gdk_bbp.c
--- a/gdk/gdk_bbp.c
+++ b/gdk/gdk_bbp.c
@@ -3077,8 +3077,10 @@ decref(bat i, bool logical, bool lock, c
                        BATdelete(BBP_desc(i));
                        BBPclear(i);
                } else {
+                       MT_lock_set(&GDKswapLock(i));
                        BBP_status_off(i, BBPUNLOADING);
                        MT_cond_broadcast(&GDKswapCond(i));
+                       MT_lock_unset(&GDKswapLock(i));
                }
        }
        return refs;
@@ -3254,9 +3256,12 @@ BBPsave(BAT *b)
                if (ret == GDK_SUCCEED) {
                        ret = BATsave(b);
                }
-               /* clearing bits can be done without the lock */
+               if (lock)
+                       MT_lock_set(&GDKswapLock(bid));
                BBP_status_off(bid, BBPSAVING);
                MT_cond_broadcast(&GDKswapCond(bid));
+               if (lock)
+                       MT_lock_unset(&GDKswapLock(bid));
        }
        return ret;
 }
@@ -3313,8 +3318,10 @@ BBPfree(BAT *b)
                BBPuncacheit(bid, false);
        }
        TRC_DEBUG(BAT_, "turn off unloading %d\n", bid);
+       MT_lock_set(&GDKswapLock(bid));
        BBP_status_off(bid, BBPUNLOADING);
        MT_cond_broadcast(&GDKswapCond(bid));
+       MT_lock_unset(&GDKswapLock(bid));
        BBP_unload_dec();
        return ret;
 }
@@ -3927,8 +3934,12 @@ BBPsync(int cnt, bat *restrict subcommit
                                if (lock)
                                        MT_lock_unset(&GDKswapLock(i));
                                ret = BATsave_iter(b, &bi, size);
+                               if (lock)
+                                       MT_lock_set(&GDKswapLock(i));
                                BBP_status_off(i, BBPSAVING);
                                MT_cond_broadcast(&GDKswapCond(i));
+                               if (lock)
+                                       MT_lock_unset(&GDKswapLock(i));
                        }
                        bip = &bi;
                } else {
@@ -4009,8 +4020,12 @@ BBPsync(int cnt, bat *restrict subcommit
         * GDK_SUCCEED) */
        for (int idx = 1; idx < cnt; idx++) {
                bat i = subcommit ? subcommit[idx] : idx;
+               if (lock)
+                       MT_lock_set(&GDKswapLock(i));
                BBP_status_off(i, BBPSYNCING);
                MT_cond_broadcast(&GDKswapCond(i));
+               if (lock)
+                       MT_lock_unset(&GDKswapLock(i));
        }
 
        return ret;
diff --git a/gdk/gdk_utils.c b/gdk/gdk_utils.c
--- a/gdk/gdk_utils.c
+++ b/gdk/gdk_utils.c
@@ -1016,6 +1016,7 @@ GDKinit(opt *set, int setlen, bool embed
                        char name[MT_NAME_LEN];
                        snprintf(name, sizeof(name), "GDKswapLock%d", i);
                        MT_lock_init(&GDKbatLock[i].swap, name);
+                       snprintf(name, sizeof(name), "GDKswapCond%d", i);
                        MT_cond_init(&GDKbatLock[i].cond, name);
                }
                if (mnstr_init() < 0) {
_______________________________________________
checkin-list mailing list -- checkin-list@monetdb.org
To unsubscribe send an email to checkin-list-le...@monetdb.org

Reply via email to