Author: Armin Rigo <[email protected]>
Branch: stmgc-c4
Changeset: r66835:157e0dd6ad13
Date: 2013-09-07 18:12 +0200
http://bitbucket.org/pypy/pypy/changeset/157e0dd6ad13/

Log:    Import stmgc/4c80cba2b8ce

diff --git a/rpython/translator/stm/src_stm/et.c 
b/rpython/translator/stm/src_stm/et.c
--- a/rpython/translator/stm/src_stm/et.c
+++ b/rpython/translator/stm/src_stm/et.c
@@ -987,8 +987,12 @@
   spinlock_release(d->public_descriptor->collection_lock);
 
   /* clear memory registered by stm_clear_on_abort */
-  if (stm_to_clear_on_abort)
-    memset(stm_to_clear_on_abort, 0, stm_bytes_to_clear_on_abort);
+  if (d->mem_clear_on_abort)
+    memset(d->mem_clear_on_abort, 0, d->mem_bytes_to_clear_on_abort);
+
+  /* invoke the callbacks registered by stm_call_on_abort */
+  stm_invoke_callbacks_on_abort(d);
+  stm_clear_callbacks_on_abort(d);
 
   dprintf(("\n"
           "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"
@@ -1483,6 +1487,10 @@
   d->num_commits++;
   d->active = 0;
   stm_stop_sharedlock();
+
+  /* clear the list of callbacks that would have been called
+     on abort */
+  stm_clear_callbacks_on_abort(d);
 }
 
 /************************************************************/
diff --git a/rpython/translator/stm/src_stm/et.h 
b/rpython/translator/stm/src_stm/et.h
--- a/rpython/translator/stm/src_stm/et.h
+++ b/rpython/translator/stm/src_stm/et.h
@@ -184,6 +184,9 @@
   struct tx_descriptor *tx_prev, *tx_next;
   int tcolor;
   pthread_t pthreadid;
+  void *mem_clear_on_abort;
+  size_t mem_bytes_to_clear_on_abort;
+  struct G2L callbacks_on_abort;
 };
 
 extern __thread struct tx_descriptor *thread_descriptor;
diff --git a/rpython/translator/stm/src_stm/extra.c 
b/rpython/translator/stm/src_stm/extra.c
--- a/rpython/translator/stm/src_stm/extra.c
+++ b/rpython/translator/stm/src_stm/extra.c
@@ -15,13 +15,46 @@
 }
 
 
-__thread void *stm_to_clear_on_abort = NULL;
-__thread size_t stm_bytes_to_clear_on_abort;
-
 void stm_clear_on_abort(void *start, size_t bytes)
 {
-    stm_to_clear_on_abort = start;
-    stm_bytes_to_clear_on_abort = bytes;
+    struct tx_descriptor *d = thread_descriptor;
+    assert(d != NULL);
+    d->mem_clear_on_abort = start;
+    d->mem_bytes_to_clear_on_abort = bytes;
+}
+
+void stm_call_on_abort(void *key, void callback(void *))
+{
+    struct tx_descriptor *d = thread_descriptor;
+    if (callback == NULL) {
+        /* ignore the return value: unregistered keys can be
+           "deleted" again */
+        g2l_delete_item(&d->callbacks_on_abort, (gcptr)key);
+    }
+    else {
+        /* double-registering the same key will crash */
+        g2l_insert(&d->callbacks_on_abort, (gcptr)key, (gcptr)callback);
+    }
+}
+
+void stm_clear_callbacks_on_abort(struct tx_descriptor *d)
+{
+    if (g2l_any_entry(&d->callbacks_on_abort))
+        g2l_clear(&d->callbacks_on_abort);
+}
+
+void stm_invoke_callbacks_on_abort(struct tx_descriptor *d)
+{
+    wlog_t *item;
+    G2L_LOOP_FORWARD(d->callbacks_on_abort, item) {
+        void *key = (void *)item->addr;
+        void (*callback)(void *) = (void(*)(void *))item->val;
+        assert(key != NULL);
+        assert(callback != NULL);
+
+        callback(key);
+
+    } G2L_LOOP_END;
 }
 
 
diff --git a/rpython/translator/stm/src_stm/extra.h 
b/rpython/translator/stm/src_stm/extra.h
--- a/rpython/translator/stm/src_stm/extra.h
+++ b/rpython/translator/stm/src_stm/extra.h
@@ -18,5 +18,7 @@
 size_t stm_decode_abort_info(struct tx_descriptor *d, long long elapsed_time,
                              int abort_reason, struct tx_abort_info *output);
 void stm_visit_abort_info(struct tx_descriptor *d, void (*visit)(gcptr *));
+void stm_clear_callbacks_on_abort(struct tx_descriptor *d);
+void stm_invoke_callbacks_on_abort(struct tx_descriptor *d);
 
 #endif
diff --git a/rpython/translator/stm/src_stm/gcpage.c 
b/rpython/translator/stm/src_stm/gcpage.c
--- a/rpython/translator/stm/src_stm/gcpage.c
+++ b/rpython/translator/stm/src_stm/gcpage.c
@@ -208,7 +208,8 @@
         //stm_dbgmem_not_used(obj, size_class * WORD, 0);
     }
     else {
-        g2l_delete_item(&gcp->nonsmall_objects, obj);
+        int deleted = g2l_delete_item(&gcp->nonsmall_objects, obj);
+        assert(deleted);
         stm_free(obj);
     }
 }
@@ -235,7 +236,8 @@
     assert(obj->h_tid & GCFLAG_PUBLIC);
 
     stmgcpage_acquire_global_lock();
-    g2l_delete_item(&registered_stubs, obj);
+    int deleted = g2l_delete_item(&registered_stubs, obj);
+    assert(deleted);
     stmgcpage_release_global_lock();
     dprintf(("unregistered %p\n", obj));
 }
diff --git a/rpython/translator/stm/src_stm/lists.c 
b/rpython/translator/stm/src_stm/lists.c
--- a/rpython/translator/stm/src_stm/lists.c
+++ b/rpython/translator/stm/src_stm/lists.c
@@ -133,15 +133,15 @@
   *(char **)p = (char *)wlog;
 }
 
-void g2l_delete_item(struct G2L *g2l, gcptr addr)
+int g2l_delete_item(struct G2L *g2l, gcptr addr)
 {
     wlog_t *entry;
     G2L_FIND(*g2l, addr, entry, goto missing);
     entry->addr = NULL;
-    return;
+    return 1;
 
  missing:
-    stm_fatalerror("g2l_delete_item: item %p not in dict", addr);
+    return 0;
 }
 
 /************************************************************/
diff --git a/rpython/translator/stm/src_stm/lists.h 
b/rpython/translator/stm/src_stm/lists.h
--- a/rpython/translator/stm/src_stm/lists.h
+++ b/rpython/translator/stm/src_stm/lists.h
@@ -114,7 +114,7 @@
 wlog_t *_g2l_find(char *entry, gcptr addr);
 void _g2l_compress(struct G2L *g2l);
 void g2l_insert(struct G2L *g2l, gcptr addr, gcptr val);
-void g2l_delete_item(struct G2L *g2l, gcptr addr);
+int g2l_delete_item(struct G2L *g2l, gcptr addr);
 
 static inline int g2l_contains(struct G2L *g2l, gcptr addr)
 {
diff --git a/rpython/translator/stm/src_stm/revision 
b/rpython/translator/stm/src_stm/revision
--- a/rpython/translator/stm/src_stm/revision
+++ b/rpython/translator/stm/src_stm/revision
@@ -1,1 +1,1 @@
-24b6be3aaa67
+4c80cba2b8ce
diff --git a/rpython/translator/stm/src_stm/stmgc.h 
b/rpython/translator/stm/src_stm/stmgc.h
--- a/rpython/translator/stm/src_stm/stmgc.h
+++ b/rpython/translator/stm/src_stm/stmgc.h
@@ -176,10 +176,14 @@
 
 /* Clear some memory when aborting a transaction in the current
    thread. This is a provisional API. The information is stored
-   thread-locally and belongs to the current thread. */
+   in the current tx_descriptor. */
 void stm_clear_on_abort(void *start, size_t bytes);
-extern __thread void *stm_to_clear_on_abort;
-extern __thread size_t stm_bytes_to_clear_on_abort;
+
+/* If the current transaction aborts later, invoke 'callback(key)'.
+   If the current transaction commits, then the callback is forgotten.
+   You can only register one callback per key.  You can call
+   'stm_call_on_abort(key, NULL)' to cancel an existing callback. */
+void stm_call_on_abort(void *key, void callback(void *));
 
 /* only user currently is stm_allocate_public_integer_address() */
 void stm_register_integer_address(intptr_t);
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to