Author: Armin Rigo <[email protected]>
Branch: c7-refactor
Changeset: r734:b8d2ad0cb59c
Date: 2014-02-14 17:21 +0100
http://bitbucket.org/pypy/stmgc/changeset/b8d2ad0cb59c/
Log: in-progress
diff --git a/c7/stm/core.c b/c7/stm/core.c
--- a/c7/stm/core.c
+++ b/c7/stm/core.c
@@ -5,7 +5,14 @@
void _stm_write_slowpath(object_t *obj)
{
- abort();
+ assert(_running_transaction());
+
+ LIST_APPEND(STM_PSEGMENT->old_objects_to_trace, obj);
+
+ obj->stm_flags |= GCFLAG_WRITE_BARRIER_CALLED;
+ stm_read(obj);
+
+ //...
}
static void reset_transaction_read_version(void)
@@ -45,6 +52,8 @@
STM_SEGMENT->transaction_read_version = old_rv + 1;
if (UNLIKELY(old_rv == 0xff))
reset_transaction_read_version();
+
+ assert(list_is_empty(STM_PSEGMENT->old_objects_to_trace));
}
diff --git a/c7/stm/core.h b/c7/stm/core.h
--- a/c7/stm/core.h
+++ b/c7/stm/core.h
@@ -51,11 +51,16 @@
struct stm_priv_segment_info_s {
struct stm_segment_info_s pub;
+ struct list_s *old_objects_to_trace;
};
static char *stm_object_pages;
static stm_thread_local_t *stm_thread_locals = NULL;
+#ifdef STM_TESTS
+static char *stm_other_pages;
+#endif
+
#define REAL_ADDRESS(segment_base, src) ((segment_base) + (uintptr_t)(src))
@@ -76,3 +81,4 @@
}
static bool _is_tl_registered(stm_thread_local_t *tl);
+static bool _running_transaction(void);
diff --git a/c7/stm/gcpage.c b/c7/stm/gcpage.c
--- a/c7/stm/gcpage.c
+++ b/c7/stm/gcpage.c
@@ -14,6 +14,8 @@
char *addr = large_malloc(size_rounded_up);
object_t* o = (object_t *)(addr - stm_object_pages);
- memset(REAL_ADDRESS(STM_SEGMENT->segment_base, o), 0, size_rounded_up);
+ long i;
+ for (i = 0; i < NB_SEGMENTS; i++)
+ memset(REAL_ADDRESS(get_segment_base(i), o), 0, size_rounded_up);
return o;
}
diff --git a/c7/stm/list.c b/c7/stm/list.c
new file mode 100644
--- /dev/null
+++ b/c7/stm/list.c
@@ -0,0 +1,33 @@
+#ifndef _STM_CORE_H_
+# error "must be compiled via stmgc.c"
+#endif
+
+
+#define LIST_SETSIZE(n) (sizeof(struct list_s) + LIST_ITEMSSIZE(n))
+#define LIST_ITEMSSIZE(n) ((n) * sizeof(uintptr_t))
+#define LIST_OVERCNT(n) (33 + ((((n) / 2) * 3) | 1))
+
+static struct list_s *list_create(void)
+{
+ uintptr_t initial_allocation = 32;
+ struct list_s *lst = malloc(LIST_SETSIZE(initial_allocation));
+ if (lst == NULL) {
+ perror("out of memory in list_create");
+ abort();
+ }
+ lst->count = 0;
+ lst->last_allocated = initial_allocation - 1;
+ return lst;
+}
+
+static struct list_s *_list_grow(struct list_s *lst, uintptr_t nalloc)
+{
+ nalloc = LIST_OVERCNT(nalloc);
+ lst = realloc(lst, LIST_SETSIZE(nalloc));
+ if (lst == NULL) {
+ perror("out of memory in _list_grow");
+ abort();
+ }
+ lst->last_allocated = nalloc - 1;
+ return lst;
+}
diff --git a/c7/stm/list.h b/c7/stm/list.h
new file mode 100644
--- /dev/null
+++ b/c7/stm/list.h
@@ -0,0 +1,64 @@
+#include <stdlib.h>
+
+struct list_s {
+ uintptr_t count;
+ uintptr_t last_allocated;
+ uintptr_t items[];
+};
+
+static struct list_s *list_create(void);
+
+static inline void list_free(struct list_s *lst)
+{
+ free(lst);
+}
+
+
+static struct list_s *_list_grow(struct list_s *, uintptr_t);
+
+static inline struct list_s *list_append(struct list_s *lst, uintptr_t item)
+{
+ uintptr_t index = lst->count++;
+ if (UNLIKELY(index > lst->last_allocated))
+ lst = _list_grow(lst, index);
+ lst->items[index] = item;
+ return lst;
+}
+
+#define LIST_APPEND(lst, e) ((lst) = list_append((lst), (uintptr_t)(e)))
+
+
+static inline void list_clear(struct list_s *lst)
+{
+ lst->count = 0;
+}
+
+static inline bool list_is_empty(struct list_s *lst)
+{
+ return (lst->count == 0);
+}
+
+static inline bool list_count(struct list_s *lst)
+{
+ return lst->count;
+}
+
+static inline uintptr_t list_pop_item(struct list_s *lst)
+{
+ return lst->items[--lst->count];
+}
+
+static inline uintptr_t list_item(struct list_s *lst, uintptr_t index)
+{
+ return lst->items[index];
+}
+
+#define LIST_FOREACH_R(lst, TYPE, CODE) \
+ do { \
+ struct list_s *_lst = (lst); \
+ uintptr_t _i; \
+ for (_i = _lst->count; _i--; ) { \
+ TYPE item = (TYPE)_lst->items[_i]; \
+ CODE; \
+ } \
+ } while (0)
diff --git a/c7/stm/setup.c b/c7/stm/setup.c
--- a/c7/stm/setup.c
+++ b/c7/stm/setup.c
@@ -39,6 +39,9 @@
long i;
for (i = 0; i < NB_SEGMENTS; i++) {
char *segment_base = get_segment_base(i);
+#ifdef STM_TESTS
+ stm_other_pages = segment_base;
+#endif
/* In each segment, the first page is where TLPREFIX'ed
NULL accesses land. We mprotect it so that accesses fail. */
@@ -59,6 +62,7 @@
struct stm_priv_segment_info_s *pr = get_priv_segment(i);
pr->pub.segment_num = i;
pr->pub.segment_base = segment_base;
+ pr->old_objects_to_trace = list_create();
}
/* Make the nursery pages shared. The other pages are
@@ -85,6 +89,12 @@
{
/* This function is called during testing, but normal programs don't
need to call it. */
+ long i;
+ for (i = 0; i < NB_SEGMENTS; i++) {
+ struct stm_priv_segment_info_s *pr = get_priv_segment(i);
+ list_free(pr->old_objects_to_trace);
+ }
+
munmap(stm_object_pages, TOTAL_MEMORY);
stm_object_pages = NULL;
diff --git a/c7/stm/sync.c b/c7/stm/sync.c
--- a/c7/stm/sync.c
+++ b/c7/stm/sync.c
@@ -81,6 +81,11 @@
sem_post(&segments_ctl.semaphore);
}
+static bool _running_transaction(void)
+{
+ return (STM_SEGMENT->running_thread != NULL);
+}
+
bool _stm_in_transaction(stm_thread_local_t *tl)
{
int num = tl->associated_segment_num;
diff --git a/c7/stmgc.c b/c7/stmgc.c
--- a/c7/stmgc.c
+++ b/c7/stmgc.c
@@ -1,11 +1,13 @@
#define _GNU_SOURCE
#include "stmgc.h"
+#include "stm/list.h"
#include "stm/core.h"
#include "stm/pages.h"
#include "stm/sync.h"
#include "stm/largemalloc.h"
#include "stm/misc.c"
+#include "stm/list.c"
#include "stm/pages.c"
#include "stm/prebuilt.c"
#include "stm/gcpage.c"
diff --git a/c7/test/support.py b/c7/test/support.py
--- a/c7/test/support.py
+++ b/c7/test/support.py
@@ -35,6 +35,7 @@
typedef struct {
object_t **shadowstack, **shadowstack_base;
+ int associated_segment_num;
...;
} stm_thread_local_t;
@@ -339,7 +340,7 @@
def stm_get_real_address(obj):
return lib._stm_real_address(ffi.cast('object_t*', obj))
-
+
def stm_get_segment_address(ptr):
return int(ffi.cast('uintptr_t', lib._stm_segment_address(ptr)))
@@ -423,6 +424,12 @@
assert not lib._stm_in_transaction(tl)
lib._stm_start_transaction(tl, ffi.cast("stm_jmpbuf_t *", -1))
assert lib._stm_in_transaction(tl)
+ #
+ seen = set()
+ for tl1 in self.tls:
+ if lib._stm_in_transaction(tl1):
+ assert tl1.associated_segment_num not in seen
+ seen.add(tl1.associated_segment_num)
def commit_transaction(self):
tl = self.tls[self.current_thread]
diff --git a/c7/test/test_basic.py b/c7/test/test_basic.py
--- a/c7/test/test_basic.py
+++ b/c7/test/test_basic.py
@@ -61,13 +61,16 @@
def test_write_on_old(self):
lp1 = stm_allocate_old(16)
self.start_transaction()
+ assert stm_get_char(lp1) == '\0'
stm_write(lp1)
assert stm_was_written(lp1)
stm_set_char(lp1, 'a')
+ assert stm_get_char(lp1) == 'a'
self.switch(1)
self.start_transaction()
- stm_read(lp1)
+ assert not stm_was_read(lp1)
+ assert stm_get_char(lp1) == '\0'
assert stm_was_read(lp1)
assert stm_get_char(lp1) == '\0'
self.commit_transaction()
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit