[pypy-commit] stmgc default: add atomic transactions in demo_random
Raemi
noreply at buildbot.pypy.org
Mon Jul 1 12:33:11 CEST 2013
Author: Remi Meier <meierrem at student.ethz.ch>
Branch:
Changeset: r328:6eac0903bcb9
Date: 2013-07-01 12:32 +0200
http://bitbucket.org/pypy/stmgc/changeset/6eac0903bcb9/
Log: add atomic transactions in demo_random
diff --git a/c4/demo_random.c b/c4/demo_random.c
--- a/c4/demo_random.c
+++ b/c4/demo_random.c
@@ -60,6 +60,7 @@
int num_roots_outside_perform;
int steps_left;
int interruptible;
+ int atomic;
};
__thread struct thread_data td;
@@ -74,6 +75,24 @@
(P->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED);
}
+static void inc_atomic()
+{
+ assert(td.interruptible);
+ assert(stm_atomic(0) == td.atomic);
+ td.atomic++;
+ stm_atomic(1);
+ assert(stm_atomic(0) == td.atomic);
+}
+
+static void dec_atomic()
+{
+ assert(td.interruptible);
+ assert(stm_atomic(0) == td.atomic);
+ td.atomic--;
+ stm_atomic(-1);
+ assert(stm_atomic(0) == td.atomic);
+}
+
int get_rand(int max)
{
return (int)(rand_r(&td.thread_seed) % (unsigned int)max);
@@ -254,7 +273,8 @@
td.thread_seed = default_seed++;
td.steps_left = STEPS_PER_THREAD;
td.interruptible = 0;
-
+ td.atomic = 0;
+
td.num_roots = PREBUILT + NUMROOTS;
for (i = 0; i < PREBUILT; i++) {
if (i % 3 == 0) {
@@ -303,7 +323,7 @@
gcptr simple_events(gcptr p, gcptr _r, gcptr _sr)
{
nodeptr w_r;
- int k = get_rand(8);
+ int k = get_rand(11);
int num = get_rand(td.num_roots);
switch (k) {
case 0: // remove a root
@@ -338,6 +358,18 @@
check(p);
w_r->next = (struct node*)p;
break;
+ case 8:
+ if (td.interruptible) {
+ inc_atomic();
+ }
+ break;
+ case 9:
+ case 10:
+ /* more likely to be less atomic */
+ if (td.atomic) {
+ dec_atomic();
+ }
+ break;
}
return p;
}
@@ -469,7 +501,7 @@
td.num_roots = td.num_roots_outside_perform;
// done & overwritten by the following pop_roots():
// copy_roots(td.roots_outside_perform, td.roots, td.num_roots);
-
+ td.atomic = 0; // may be set differently on abort
// refresh td.roots:
gcptr end_marker = stm_pop_root();
assert(end_marker == END_MARKER_ON || end_marker == END_MARKER_OFF);
@@ -490,14 +522,26 @@
int run_me()
{
gcptr p = NULL;
- while (td.steps_left-->0) {
+ while (td.steps_left-->0 || td.atomic) {
if (td.steps_left % 8 == 0)
fprintf(stdout, "#");
p = do_step(p);
- if (p == (gcptr)-1)
- return -1;
+ if (p == (gcptr)-1) {
+ if (td.atomic) {
+ // can't break, well, we could return to perform_transaction
+ // while being atomic. (TODO)
+ // may be true when major gc requested:
+ // assert(stm_should_break_transaction() == 0);
+ assert(stm_atomic(0) == td.atomic);
+ p = NULL;
+ }
+ else {
+ assert(stm_atomic(0) == 0);
+ return -1;
+ }
+ }
}
return 0;
}
diff --git a/c4/et.c b/c4/et.c
--- a/c4/et.c
+++ b/c4/et.c
@@ -906,6 +906,8 @@
long stm_atomic(long delta)
{
struct tx_descriptor *d = thread_descriptor;
+ if (delta) // no atomic-checks
+ dprintf(("stm_atomic(%lu)\n", delta));
d->atomic += delta;
assert(d->atomic >= 0);
update_reads_size_limit(d);
diff --git a/c4/nursery.c b/c4/nursery.c
--- a/c4/nursery.c
+++ b/c4/nursery.c
@@ -198,9 +198,6 @@
return (revision_t)p;
}
- /* XXX: think about if p->h_original needs a volatile read
- and if we need a memory fence (smp_wmb())... */
-
spinlock_acquire(d->public_descriptor->collection_lock, 'I');
/* old objects must have an h_original xOR be
the original itself.
@@ -222,7 +219,6 @@
gcptr O = stmgc_duplicate_old(p);
p->h_original = (revision_t)O;
p->h_tid |= GCFLAG_HAS_ID;
- O->h_tid |= GCFLAG_PUBLIC;
if (p->h_tid & GCFLAG_PRIVATE_FROM_PROTECTED) {
gcptr B = (gcptr)p->h_revision;
More information about the pypy-commit
mailing list