Author: Armin Rigo <[email protected]>
Branch:
Changeset: r531:0581363bf46a
Date: 2013-09-23 17:14 +0200
http://bitbucket.org/pypy/stmgc/changeset/0581363bf46a/
Log: in-progress: API for the pypy jit, with support for a custom
implementation of setjmp/longjmp.
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -1016,7 +1016,12 @@
// jump back to the setjmp_buf (this call does not return)
stm_stop_sharedlock();
- longjmp(*d->setjmp_buf, 1);
+ if (d->longjmp_callback != NULL)
+ d->longjmp_callback(d->setjmp_buf);
+ else
+ longjmp(*(jmp_buf *)d->setjmp_buf, 1);
+
+ stm_fatalerror("longjmp() call should not return");
}
void AbortTransactionAfterCollect(struct tx_descriptor *d, int reason)
@@ -1083,12 +1088,13 @@
gcptrlist_clear(&d->abortinfo);
}
-void BeginTransaction(jmp_buf* buf)
+void stm_begin_transaction(void *buf, void (*longjmp_callback)(void *))
{
struct tx_descriptor *d = thread_descriptor;
init_transaction(d);
d->active = 1;
d->setjmp_buf = buf;
+ d->longjmp_callback = longjmp_callback;
d->old_thread_local_obj = stm_thread_local_obj;
d->start_time = GetGlobalCurTime(d);
update_reads_size_limit(d);
diff --git a/c4/et.h b/c4/et.h
--- a/c4/et.h
+++ b/c4/et.h
@@ -159,7 +159,8 @@
struct tx_descriptor {
struct tx_public_descriptor *public_descriptor;
revision_t public_descriptor_index;
- jmp_buf *setjmp_buf;
+ void *setjmp_buf;
+ void(*longjmp_callback)(void *);
revision_t start_time;
revision_t my_lock;
gcptr *shadowstack;
@@ -205,7 +206,6 @@
/************************************************************/
-void BeginTransaction(jmp_buf *);
void BeginInevitableTransaction(void); /* must save roots around this call */
void CommitTransaction(void); /* must save roots around this call */
void BecomeInevitable(const char *why); /* must save roots around this call */
diff --git a/c4/stmgc.h b/c4/stmgc.h
--- a/c4/stmgc.h
+++ b/c4/stmgc.h
@@ -121,6 +121,12 @@
void stm_begin_inevitable_transaction(void);
void stm_become_inevitable(const char *reason);
+/* specialized usage: for custom setjmp/longjmp implementation.
+ Must save roots around calls. */
+void stm_begin_transaction(void *buf, void (*longjmp_callback)(void *));
+void stm_transaction_break(void *buf, void (*longjmp_callback)(void *));
+void stm_invalidate_jmp_buf(void *buf);
+
/* debugging: check if we're currently running a transaction or not. */
int stm_in_transaction(void);
diff --git a/c4/stmsync.c b/c4/stmsync.c
--- a/c4/stmsync.c
+++ b/c4/stmsync.c
@@ -176,7 +176,7 @@
d->reads_size_limit_nonatomic = limit;
}
if (!d->atomic) {
- BeginTransaction(&_jmpbuf);
+ stm_begin_transaction(&_jmpbuf, NULL);
}
else {
/* atomic transaction: a common case is that callback() returned
@@ -213,6 +213,35 @@
assert(stm_shadowstack == v_saved_value);
}
+void stm_transaction_break(void *buf, void (*longjmp_callback)(void *))
+{ /* must save roots around this call */
+ struct tx_descriptor *d = thread_descriptor;
+ if (d->atomic) {
+ assert(d->active >= 1);
+ stm_possible_safe_point();
+ }
+ else {
+ CommitTransaction();
+ if (d->active != 2) {
+ unsigned long limit = d->reads_size_limit_nonatomic;
+ if (limit != 0 && limit < (stm_regular_length_limit >> 1))
+ limit = (limit << 1) | 1;
+ else
+ limit = stm_regular_length_limit;
+ d->reads_size_limit_nonatomic = limit;
+ }
+ stm_begin_transaction(buf, longjmp_callback);
+ }
+}
+
+void stm_invalidate_jmp_buf(void *buf)
+{ /* must save roots around this call */
+ struct tx_descriptor *d = thread_descriptor;
+ if (d->setjmp_buf == buf) {
+ BecomeInevitable("stm_invalidate_jmp_buf with atomic");
+ }
+}
+
void stm_commit_transaction(void)
{ /* must save roots around this call */
struct tx_descriptor *d = thread_descriptor;
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit