[pypy-commit] stmgc default: start using a global commit log
Raemi
noreply at buildbot.pypy.org
Wed Sep 3 14:55:41 CEST 2014
Author: Remi Meier <remi.meier at inf.ethz.ch>
Branch:
Changeset: r1340:03fc557e29dd
Date: 2014-09-03 14:56 +0200
http://bitbucket.org/pypy/stmgc/changeset/03fc557e29dd/
Log: start using a global commit log
diff --git a/c8/stm/core.c b/c8/stm/core.c
--- a/c8/stm/core.c
+++ b/c8/stm/core.c
@@ -3,6 +3,85 @@
#endif
+/* ############# commit log ############# */
+
+void _dbg_print_commit_log()
+{
+ struct stm_commit_log_entry_s *cl = &commit_log_root;
+
+ fprintf(stderr, "root (%p, %d)\n", cl->next, cl->segment_num);
+ while ((cl = cl->next)) {
+ size_t i = 0;
+ fprintf(stderr, "elem (%p, %d)\n", cl->next, cl->segment_num);
+ object_t *obj;
+ do {
+ obj = cl->written[i];
+ fprintf(stderr, "-> %p\n", obj);
+ i++;
+ } while ((obj = cl->written[i]));
+ }
+}
+
+void stm_validate(void *free_if_abort)
+{
+ struct stm_commit_log_entry_s *cl = STM_PSEGMENT->last_commit_log_entry;
+
+ /* Don't check 'cl'. This entry is already checked */
+ while ((cl = cl->next)) {
+ size_t i = 0;
+ OPT_ASSERT(cl->segment_num >= 0 && cl->segment_num < NB_SEGMENTS);
+
+ object_t *obj;
+ while ((obj = cl->written[i])) {
+ /* XXX: update our copies */
+
+ if (_stm_was_read(obj)) {
+ free(free_if_abort);
+ stm_abort_transaction();
+ }
+
+ i++;
+ };
+
+ /* last fully validated entry */
+ STM_PSEGMENT->last_commit_log_entry = cl;
+ }
+}
+
+static struct stm_commit_log_entry_s *_create_commit_log_entry()
+{
+ struct list_s *lst = STM_PSEGMENT->modified_old_objects;
+ size_t count = list_count(lst);
+ size_t byte_len = sizeof(struct stm_commit_log_entry_s) + (count + 1) * sizeof(object_t*);
+ struct stm_commit_log_entry_s *result = malloc(byte_len);
+ int i;
+
+ result->next = NULL;
+ result->segment_num = STM_SEGMENT->segment_num;
+ for (i = 0; i < count; i++) {
+ result->written[i] = (object_t*)list_item(lst, i);
+ }
+ result->written[count] = NULL;
+
+ return result;
+}
+
+static void _validate_and_add_to_commit_log()
+{
+ struct stm_commit_log_entry_s *new;
+ void* *to;
+
+ new = _create_commit_log_entry();
+ fprintf(stderr,"%p\n", new);
+ do {
+ stm_validate(new);
+
+ to = (void **)&(STM_PSEGMENT->last_commit_log_entry->next);
+ } while (!__sync_bool_compare_and_swap((void**)to, (void**)NULL, (void**)new));
+}
+
+/* ############# STM ############# */
+
void _stm_write_slowpath(object_t *obj)
{
assert(_seems_to_be_running_transaction());
@@ -159,6 +238,8 @@
minor_collection(1);
+ _validate_and_add_to_commit_log();
+
s_mutex_lock();
assert(STM_SEGMENT->nursery_end == NURSERY_END);
diff --git a/c8/stm/core.h b/c8/stm/core.h
--- a/c8/stm/core.h
+++ b/c8/stm/core.h
@@ -52,12 +52,22 @@
struct list_s *objects_pointing_to_nursery;
uint8_t privatization_lock;
+ struct stm_commit_log_entry_s *last_commit_log_entry;
+
/* For debugging */
#ifndef NDEBUG
pthread_t running_pthread;
#endif
};
+/* Commit Log things */
+struct stm_commit_log_entry_s {
+ struct stm_commit_log_entry_s *next;
+ int segment_num;
+ object_t *written[]; /* terminated with a NULL ptr */
+};
+static struct stm_commit_log_entry_s commit_log_root = {NULL, -1};
+
static char *stm_object_pages;
static int stm_object_pages_fd;
diff --git a/c8/stm/setup.c b/c8/stm/setup.c
--- a/c8/stm/setup.c
+++ b/c8/stm/setup.c
@@ -107,6 +107,7 @@
pr->pub.segment_base = segment_base;
pr->modified_old_objects = list_create();
pr->objects_pointing_to_nursery = list_create();
+ pr->last_commit_log_entry = &commit_log_root;
pr->pub.transaction_read_version = 0xff;
}
diff --git a/c8/stmgc.h b/c8/stmgc.h
--- a/c8/stmgc.h
+++ b/c8/stmgc.h
@@ -67,6 +67,7 @@
char *_stm_real_address(object_t *o);
#ifdef STM_TESTS
#include <stdbool.h>
+void stm_validate(void *free_if_abort);
bool _stm_was_read(object_t *obj);
bool _stm_was_written(object_t *obj);
diff --git a/c8/test/support.py b/c8/test/support.py
--- a/c8/test/support.py
+++ b/c8/test/support.py
@@ -31,6 +31,8 @@
void stm_teardown(void);
void stm_register_thread_local(stm_thread_local_t *tl);
void stm_unregister_thread_local(stm_thread_local_t *tl);
+void stm_validate(void *free_if_abort);
+bool _check_stm_validate();
bool _checked_stm_write(object_t *obj);
bool _stm_was_read(object_t *obj);
@@ -124,6 +126,10 @@
CHECKED(stm_abort_transaction());
}
+bool _check_stm_validate(void) {
+ CHECKED(stm_validate(NULL));
+}
+
#undef CHECKED
@@ -314,6 +320,9 @@
def stm_was_written_card(o):
return lib._stm_was_written_card(o)
+def stm_validate():
+ if lib._check_stm_validate():
+ raise Conflict()
def stm_start_safe_point():
lib._stm_start_safe_point()
@@ -433,6 +442,7 @@
#
if lib._stm_in_transaction(tl2):
lib._stm_test_switch(tl2)
+ stm_validate() # can raise
def push_root(self, o):
assert 0
More information about the pypy-commit
mailing list