Author: Armin Rigo <[email protected]>
Branch: stm-gc
Changeset: r52095:ca1bda35d3ab
Date: 2012-02-04 18:07 +0100
http://bitbucket.org/pypy/pypy/changeset/ca1bda35d3ab/
Log: In-progress. Starting work on the GC/src_stm interface.
diff --git a/pypy/config/translationoption.py b/pypy/config/translationoption.py
--- a/pypy/config/translationoption.py
+++ b/pypy/config/translationoption.py
@@ -58,7 +58,8 @@
# gc
ChoiceOption("gc", "Garbage Collection Strategy",
["boehm", "ref", "marksweep", "semispace", "statistics",
- "generation", "hybrid", "markcompact", "minimark", "none"],
+ "generation", "hybrid", "markcompact", "minimark", "none",
+ "stmgc"],
"ref", requires={
"ref": [("translation.rweakref", False), # XXX
("translation.gctransformer", "ref")],
@@ -73,6 +74,8 @@
("translation.gctransformer", "boehm")],
"markcompact": [("translation.gctransformer",
"framework")],
"minimark": [("translation.gctransformer", "framework")],
+ "stmgc": [("translation.gctransformer", "framework"),
+ ("translation.gcrootfinder", "none")], # XXX
},
cmdline="--gc"),
ChoiceOption("gctransformer", "GC transformer that is used - internal",
@@ -90,7 +93,7 @@
default=IS_64_BITS, cmdline="--gcremovetypeptr"),
ChoiceOption("gcrootfinder",
"Strategy for finding GC Roots (framework GCs only)",
- ["n/a", "shadowstack", "asmgcc"],
+ ["n/a", "shadowstack", "asmgcc", "none"],
"shadowstack",
cmdline="--gcrootfinder",
requires={
@@ -103,7 +106,8 @@
BoolOption("thread", "enable use of threading primitives",
default=False, cmdline="--thread"),
BoolOption("stm", "enable use of Software Transactional Memory",
- default=False, cmdline="--stm"),
+ default=False, cmdline="--stm",
+ requires=[("translation.gc", "stmgc")]),
BoolOption("sandbox", "Produce a fully-sandboxed executable",
default=False, cmdline="--sandbox",
requires=[("translation.thread", False)],
diff --git a/pypy/rpython/memory/gc/base.py b/pypy/rpython/memory/gc/base.py
--- a/pypy/rpython/memory/gc/base.py
+++ b/pypy/rpython/memory/gc/base.py
@@ -440,6 +440,7 @@
"hybrid": "hybrid.HybridGC",
"markcompact" : "markcompact.MarkCompactGC",
"minimark" : "minimark.MiniMarkGC",
+ "stmgc": "stmgc.StmGC",
}
try:
modulename, classname = classes[config.translation.gc].split('.')
diff --git a/pypy/rpython/memory/gc/stmgc.py b/pypy/rpython/memory/gc/stmgc.py
--- a/pypy/rpython/memory/gc/stmgc.py
+++ b/pypy/rpython/memory/gc/stmgc.py
@@ -24,11 +24,6 @@
return fn
-class StmOperations(object):
- def _freeze_(self):
- return True
-
-
class StmGC(GCBase):
_alloc_flavor_ = "raw"
inline_simple_malloc = True
@@ -50,10 +45,23 @@
('pending_list', llmemory.Address),
)
- def __init__(self, config, stm_operations,
+ TRANSLATION_PARAMS = {
+ 'stm_operations': 'use_real_one',
+ 'max_nursery_size': 400*1024*1024, # XXX 400MB
+ }
+
+ def __init__(self, config, stm_operations='use_emulator',
max_nursery_size=1024,
**kwds):
GCBase.__init__(self, config, **kwds)
+ #
+ if isinstance(stm_operations, str):
+ assert stm_operations == 'use_real_one', (
+ "XXX not provided so far: stm_operations == %r" % (
+ stm_operations,))
+ from pypy.translator.stm.stmgcintf import StmOperations
+ stm_operations = StmOperations()
+ #
self.stm_operations = stm_operations
self.collector = Collector(self)
self.max_nursery_size = max_nursery_size
@@ -80,7 +88,7 @@
"""Setup a thread. Allocates the thread-local data structures.
Must be called only once per OS-level thread."""
tls = lltype.malloc(self.GCTLS, flavor='raw')
- self.stm_operations.set_tls(self, llmemory.cast_ptr_to_adr(tls))
+ self.stm_operations.set_tls(llmemory.cast_ptr_to_adr(tls))
tls.nursery_start = self._alloc_nursery()
tls.nursery_size = self.max_nursery_size
tls.nursery_free = tls.nursery_start
@@ -107,7 +115,7 @@
"""Teardown a thread. Call this just before the OS-level thread
disappears."""
tls = self.collector.get_tls()
- self.stm_operations.set_tls(self, NULL)
+ self.stm_operations.del_tls()
self._free_nursery(tls.nursery_start)
lltype.free(tls, flavor='raw')
@@ -157,6 +165,11 @@
return llmemory.cast_adr_to_ptr(obj, llmemory.GCREF)
+ def malloc_varsize_clear(self, typeid, length, size, itemsize,
+ offset_to_length):
+ raise NotImplementedError
+
+
def _malloc_local_raw(self, tls, size):
# for _stm_write_barrier_global(): a version of malloc that does
# no initialization of the malloc'ed object
@@ -168,6 +181,10 @@
return obj
+ def collect(self, gen=0):
+ raise NotImplementedError
+
+
@always_inline
def combine(self, typeid16, flags):
return llop.combine_ushort(lltype.Signed, typeid16, flags)
diff --git a/pypy/rpython/memory/gc/test/test_stmgc.py
b/pypy/rpython/memory/gc/test/test_stmgc.py
--- a/pypy/rpython/memory/gc/test/test_stmgc.py
+++ b/pypy/rpython/memory/gc/test/test_stmgc.py
@@ -22,24 +22,26 @@
threadnum = 0 # 0 = main thread; 1,2,3... = transactional threads
- def set_tls(self, gc, tls):
+ def set_tls(self, tls):
assert lltype.typeOf(tls) == llmemory.Address
+ assert tls
if self.threadnum == 0:
assert not hasattr(self, '_tls_dict')
- assert not hasattr(self, '_gc')
self._tls_dict = {0: tls}
self._tldicts = {0: {}}
self._tldicts_iterators = {}
- self._gc = gc
self._transactional_copies = []
else:
- assert self._gc is gc
self._tls_dict[self.threadnum] = tls
self._tldicts[self.threadnum] = {}
def get_tls(self):
return self._tls_dict[self.threadnum]
+ def del_tls(self):
+ del self._tls_dict[self.threadnum]
+ del self._tldicts[self.threadnum]
+
def tldict_lookup(self, obj):
assert lltype.typeOf(obj) == llmemory.Address
assert obj
@@ -48,6 +50,7 @@
def tldict_add(self, obj, localobj):
assert lltype.typeOf(obj) == llmemory.Address
+ assert lltype.typeOf(localobj) == llmemory.Address
tldict = self._tldicts[self.threadnum]
assert obj not in tldict
tldict[obj] = localobj
@@ -63,6 +66,7 @@
except StopIteration:
state[1] = None
state[2] = None
+ del self._tldicts_iterators[self.threadnum]
return False
state[1] = next_key
state[2] = next_value
@@ -130,6 +134,7 @@
config = get_pypy_config(translating=True).translation
self.gc = self.GCClass(config, FakeStmOperations(),
translated_to_c=False)
+ self.gc.stm_operations._gc = self.gc
self.gc.DEBUG = True
self.gc.get_size = fake_get_size
self.gc.trace = fake_trace
diff --git a/pypy/translator/stm/src_stm/et.c b/pypy/translator/stm/src_stm/et.c
--- a/pypy/translator/stm/src_stm/et.c
+++ b/pypy/translator/stm/src_stm/et.c
@@ -62,6 +62,7 @@
#define OTHERINEV_REASONS 5
struct tx_descriptor {
+ void *rpython_tls_object;
jmp_buf *setjmp_buf;
owner_version_t start_time;
owner_version_t end_time;
@@ -481,7 +482,7 @@
}
-void stm_descriptor_init(void)
+static struct tx_descriptor *descriptor_init(void)
{
assert(thread_descriptor == NULL_TX);
if (1) /* for hg diff */
@@ -507,10 +508,11 @@
(long)pthread_self());
PYPY_DEBUG_STOP("stm-init");
#endif
+ return d;
}
}
-void stm_descriptor_done(void)
+static void descriptor_done(void)
{
struct tx_descriptor *d = thread_descriptor;
assert(d != NULL_TX);
@@ -840,4 +842,20 @@
return d->my_lock_word;
}
+
+void stm_set_tls(void *newtls)
+{
+ descriptor_init()->rpython_tls_object = newtls;
+}
+
+void *stm_get_tls(void)
+{
+ return thread_descriptor->rpython_tls_object;
+}
+
+void stm_del_tls(void)
+{
+ descriptor_done();
+}
+
#endif /* PYPY_NOT_MAIN_FILE */
diff --git a/pypy/translator/stm/src_stm/et.h b/pypy/translator/stm/src_stm/et.h
--- a/pypy/translator/stm/src_stm/et.h
+++ b/pypy/translator/stm/src_stm/et.h
@@ -11,6 +11,13 @@
#include <setjmp.h>
#include "src/commondefs.h"
+
+void stm_set_tls(void *);
+void *stm_get_tls(void);
+void stm_del_tls(void);
+
+
+
#ifdef RPY_STM_ASSERT
# define STM_CCHARP1(arg) char* arg
# define STM_EXPLAIN1(info) info
@@ -20,8 +27,6 @@
#endif
-void stm_descriptor_init(void);
-void stm_descriptor_done(void);
void* stm_perform_transaction(void*(*)(void*, long), void*);
long stm_read_word(long* addr);
void stm_write_word(long* addr, long val);
diff --git a/pypy/translator/stm/stmgcintf.py b/pypy/translator/stm/stmgcintf.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/stmgcintf.py
@@ -0,0 +1,39 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.translator.stm import _rffi_stm
+
+
+def smexternal(name, args, result):
+ return staticmethod(_rffi_stm.llexternal(name, args, result))
+
+
+class StmOperations(object):
+
+ def _freeze_(self):
+ return True
+
+ set_tls = smexternal('stm_set_tls', [llmemory.Address], lltype.Void)
+ get_tls = smexternal('stm_get_tls', [], llmemory.Address)
+ del_tls = smexternal('stm_del_tls', [], lltype.Void)
+
+ tldict_lookup = smexternal('stm_tldict_lookup', [llmemory.Address],
+ llmemory.Address)
+ tldict_add = smexternal('stm_tldict_add', [llmemory.Address] * 2,
+ lltype.Void)
+
+ enum_tldict_start = smexternal('stm_enum_tldict_start', [], lltype.Void)
+ enum_tldict_find_next = smexternal('stm_enum_tldict_find_next', [],
+ lltype.Signed)
+ enum_tldict_globalobj = smexternal('stm_enum_tldict_globalobj', [],
+ llmemory.Address)
+ enum_tldict_localobj = smexternal('stm_enum_tldict_localobj', [],
+ llmemory.Address)
+
+ stm_read_word = smexternal('stm_read_word',
+ [llmemory.Address, lltype.Signed],
+ lltype.Signed)
+
+ stm_copy_transactional_to_raw = smexternal('stm_copy_transactional_to_raw',
+ [llmemory.Address,
+ llmemory.Address,
+ lltype.Signed],
+ lltype.Void)
diff --git a/pypy/translator/stm/test/test_stmgcintf.py
b/pypy/translator/stm/test/test_stmgcintf.py
new file mode 100644
--- /dev/null
+++ b/pypy/translator/stm/test/test_stmgcintf.py
@@ -0,0 +1,14 @@
+from pypy.rpython.lltypesystem import lltype, llmemory
+from pypy.translator.stm.stmgcintf import StmOperations
+
+stm_operations = StmOperations()
+
+
+def test_set_get_del():
+ # assume that they are really thread-local; not checked here
+ s = lltype.malloc(lltype.Struct('S'), flavor='raw')
+ a = llmemory.cast_ptr_to_adr(s)
+ stm_operations.set_tls(a)
+ assert stm_operations.get_tls() == a
+ stm_operations.del_tls()
+ lltype.free(s, flavor='raw')
_______________________________________________
pypy-commit mailing list
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit