Commits

Armin Rigo committed d58564f

Fix.

Comments (0)

Files changed (2)

 }
 
 
-DuObject *_Du_AME_read_from_global(DuObject *glob)
+static inline owner_version_t prepare_read(struct tx_descriptor *d,
+                                           DuObject *glob)
 {
-    struct tx_descriptor *d = thread_descriptor;
-    wlog_t *found;
-    REDOLOG_FIND(d->redolog, glob, found, goto not_found);
-    DuObject *localobj = found->val;
-    assert(!Du_AME_GLOBAL(localobj));
-    return localobj;
-
- not_found:
- retry:;
-    owner_version_t ovt = glob->ob_version;
+    owner_version_t ovt;
+ retry:
+    ovt = glob->ob_version;
     if (IS_LOCKED_OR_NEWER(ovt, d->start_time)) {
         if (IS_LOCKED(ovt)) {
             tx_spinloop();
         validate_fast(d);
         d->start_time = newts;
     }
+}
+
+DuObject *_Du_AME_read_from_global(DuObject *glob, owner_version_t *vers_out)
+{
+    struct tx_descriptor *d = thread_descriptor;
+    wlog_t *found;
+    REDOLOG_FIND(d->redolog, glob, found, goto not_found);
+    DuObject *localobj = found->val;
+    assert(!Du_AME_GLOBAL(localobj));
+    return localobj;
+
+ not_found:
+    *vers_out = prepare_read(d, glob);
     return glob;
 }
 
 
  not_found:;
     /* We need to really make a local copy */
+    owner_version_t version;
     int size = glob->ob_type->dt_size;
     localobj = malloc(size);
     assert(localobj != NULL);
-    /* Initialize the copy by doing an stm raw copy of the bytes */
-    memcpy((char *)localobj, (char *)glob, size);
+
+    do {
+        version = prepare_read(d, glob);
+        CFENCE;
+        /* Initialize the copy by doing an stm raw copy of the bytes */
+        memcpy((char *)localobj, (char *)glob, size);
+        CFENCE;
+        /* Check the copy for validity */
+    } while (glob->ob_version != version);
+
     /* Initialize the copy's refcount to be a valid local object */
     localobj->ob_refcnt = 42;   /* XXX */
     /* Set the ob_debug_prev field to NULL and the ob_debug_next field to
 #include "../duhton.h"
 
 
-DuObject *_Du_AME_read_from_global(DuObject *glob);
+DuObject *_Du_AME_read_from_global(DuObject *glob, owner_version_t *vers_out);
 void _Du_AME_oreclist_insert(DuObject *glob);
 DuObject *_Du_AME_writebarrier(DuObject *glob);
 
 #define Du_AME_READ_START(ob)                                           \
 while (1) {                                                             \
     DuObject *__du_ame_ob = (DuObject *)(ob);                           \
-    owner_version_t __du_ame_version = 0;                               \
+    owner_version_t __du_ame_version;                                   \
     if (Du_AME_GLOBAL(__du_ame_ob)) {                                   \
-        __du_ame_ob = _Du_AME_read_from_global(__du_ame_ob);            \
+        __du_ame_ob = _Du_AME_read_from_global(__du_ame_ob,             \
+                                                &__du_ame_version);     \
         (ob) = (typeof(ob))__du_ame_ob;                                 \
-        __du_ame_version = __du_ame_ob->ob_version;                     \
         CFENCE;                                                         \
     }