Author: Brian Kearns <[email protected]>
Branch:
Changeset: r69289:d674245526d9
Date: 2014-02-23 14:01 -0500
http://bitbucket.org/pypy/pypy/changeset/d674245526d9/
Log: merge heads
diff --git a/lib-python/2.7/threading.py b/lib-python/2.7/threading.py
--- a/lib-python/2.7/threading.py
+++ b/lib-python/2.7/threading.py
@@ -244,22 +244,11 @@
if __debug__:
self._note("%s.wait(): got it", self)
else:
- # Balancing act: We can't afford a pure busy loop, so we
- # have to sleep; but if we sleep the whole timeout time,
- # we'll be unresponsive. The scheme here sleeps very
- # little at first, longer as time goes on, but never longer
- # than 20 times per second (or the timeout time remaining).
- endtime = _time() + timeout
- delay = 0.0005 # 500 us -> initial delay of 1 ms
- while True:
- gotit = waiter.acquire(0)
- if gotit:
- break
- remaining = endtime - _time()
- if remaining <= 0:
- break
- delay = min(delay * 2, remaining, .05)
- _sleep(delay)
+ # PyPy patch: use _py3k_acquire()
+ if timeout > 0:
+ gotit = waiter._py3k_acquire(True, timeout)
+ else:
+ gotit = waiter.acquire(False)
if not gotit:
if __debug__:
self._note("%s.wait(%s): timed out", self, timeout)
diff --git a/rpython/rlib/_stacklet_asmgcc.py b/rpython/rlib/_stacklet_asmgcc.py
--- a/rpython/rlib/_stacklet_asmgcc.py
+++ b/rpython/rlib/_stacklet_asmgcc.py
@@ -189,7 +189,7 @@
pypy_asm_stackwalk2 = rffi.llexternal('pypy_asm_stackwalk',
[FUNCNOARG_P,
ASM_FRAMEDATA_HEAD_PTR],
- _c.handle, sandboxsafe=True,
+ lltype.Signed, sandboxsafe=True,
_nowrapper=True)
@@ -273,6 +273,7 @@
#
h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _new_callback),
alternateanchor)
+ h = rffi.cast(_c.handle, h)
#
llop.gc_reattach_callback_pieces(lltype.Void, callback_pieces)
return self.get_result_suspstack(h)
@@ -292,6 +293,7 @@
#
h = pypy_asm_stackwalk2(llhelper(FUNCNOARG_P, _switch_callback),
alternateanchor)
+ h = rffi.cast(_c.handle, h)
#
llop.gc_reattach_callback_pieces(lltype.Void, callback_pieces)
if not h:
diff --git a/rpython/rlib/rawstorage.py b/rpython/rlib/rawstorage.py
--- a/rpython/rlib/rawstorage.py
+++ b/rpython/rlib/rawstorage.py
@@ -18,17 +18,87 @@
def raw_storage_getitem(TP, storage, index):
"NOT_RPYTHON"
+ _check_alignment(TP, index)
return rffi.cast(rffi.CArrayPtr(TP), rffi.ptradd(storage, index))[0]
def raw_storage_setitem(storage, index, item):
"NOT_RPYTHON"
- TP = rffi.CArrayPtr(lltype.typeOf(item))
- rffi.cast(TP, rffi.ptradd(storage, index))[0] = item
+ TP = lltype.typeOf(item)
+ _check_alignment(TP, index)
+ rffi.cast(rffi.CArrayPtr(TP), rffi.ptradd(storage, index))[0] = item
@specialize.arg(1)
def free_raw_storage(storage, track_allocation=True):
lltype.free(storage, flavor='raw', track_allocation=track_allocation)
+# ____________________________________________________________
+#
+# Support for possibly-unaligned accesses
+
+from rpython.jit.backend import detect_cpu
+try:
+ misaligned_is_fine = detect_cpu.autodetect().startswith('x86')
+except detect_cpu.ProcessorAutodetectError:
+ misaligned_is_fine = False
+
+
+class AlignmentError(NotImplementedError):
+ "Means that raw_storage_{get,set}item was used on unaligned memory"
+
+# Tweak? It seems a reasonable value for any system out there: requiring
+# an aligned access to be up to 8-bytes-aligned, even for 64-bit data
+# types on 32-bit systems.
+MAXIMUM_ALIGNMENT = 8
+
[email protected]()
+def _get_alignment_mask(TP):
+ size = rffi.sizeof(TP)
+ alignment = 1
+ while (size & alignment) == 0 and alignment < MAXIMUM_ALIGNMENT:
+ alignment *= 2
+ return alignment - 1
+
+def _check_alignment(TP, index):
+ """Check that the 'index' does indeed have the maximum alignment
+ for the given type."""
+ mask = _get_alignment_mask(TP)
+ if (index & mask) != 0:
+ raise AlignmentError
+
[email protected]()
+def raw_storage_getitem_unaligned(TP, storage, index):
+ if misaligned_is_fine:
+ return raw_storage_getitem(TP, storage, index)
+ mask = _get_alignment_mask(TP)
+ if (index & mask) == 0:
+ return raw_storage_getitem(TP, storage, index)
+ ptr = rffi.ptradd(storage, index)
+ with lltype.scoped_alloc(rffi.CArray(TP), 1) as s_array:
+ rffi.c_memcpy(rffi.cast(rffi.VOIDP, s_array),
+ rffi.cast(rffi.VOIDP, ptr),
+ rffi.sizeof(TP))
+ return rffi.cast(rffi.CArrayPtr(TP), s_array)[0]
+
[email protected]()
+def raw_storage_setitem_unaligned(storage, index, item):
+ if misaligned_is_fine:
+ raw_storage_setitem(storage, index, item)
+ return
+ TP = lltype.typeOf(item)
+ mask = _get_alignment_mask(TP)
+ if (index & mask) == 0:
+ raw_storage_setitem(storage, index, item)
+ return
+ ptr = rffi.ptradd(storage, index)
+ with lltype.scoped_alloc(rffi.CArray(TP), 1) as s_array:
+ rffi.cast(rffi.CArrayPtr(TP), s_array)[0] = item
+ rffi.c_memcpy(rffi.cast(rffi.VOIDP, ptr),
+ rffi.cast(rffi.VOIDP, s_array),
+ rffi.sizeof(TP))
+
+# ____________________________________________________________
+
+
class RawStorageGetitemEntry(ExtRegistryEntry):
_about_ = raw_storage_getitem
diff --git a/rpython/rlib/test/test_rawstorage.py
b/rpython/rlib/test/test_rawstorage.py
--- a/rpython/rlib/test/test_rawstorage.py
+++ b/rpython/rlib/test/test_rawstorage.py
@@ -1,23 +1,91 @@
+import py
+import sys
+from rpython.rtyper.lltypesystem import lltype
+from rpython.rlib import rawstorage
+from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage,\
+ raw_storage_setitem, raw_storage_getitem, AlignmentError,\
+ raw_storage_setitem_unaligned, raw_storage_getitem_unaligned
+from rpython.rtyper.test.tool import BaseRtypingTest
+from rpython.translator.c.test.test_genc import compile
-from rpython.rtyper.lltypesystem import lltype
-from rpython.rlib.rawstorage import alloc_raw_storage, free_raw_storage,\
- raw_storage_setitem, raw_storage_getitem
-from rpython.rtyper.test.tool import BaseRtypingTest
def test_untranslated_storage():
+ r = alloc_raw_storage(37)
+ raw_storage_setitem(r, 8, 1<<30)
+ res = raw_storage_getitem(lltype.Signed, r, 8)
+ assert res == 1<<30
+ raw_storage_setitem(r, 8, 3.14)
+ res = raw_storage_getitem(lltype.Float, r, 8)
+ assert res == 3.14
+ py.test.raises(AlignmentError, raw_storage_getitem, lltype.Signed, r, 3)
+ py.test.raises(AlignmentError, raw_storage_setitem, r, 3, 42.5)
+ free_raw_storage(r)
+
+def test_untranslated_storage_unaligned(monkeypatch):
+ monkeypatch.setattr(rawstorage, 'misaligned_is_fine', False)
r = alloc_raw_storage(15)
- raw_storage_setitem(r, 3, 1<<30)
- res = raw_storage_getitem(lltype.Signed, r, 3)
+ raw_storage_setitem_unaligned(r, 3, 1<<30)
+ res = raw_storage_getitem_unaligned(lltype.Signed, r, 3)
+ assert res == 1<<30
+ raw_storage_setitem_unaligned(r, 3, 3.14)
+ res = raw_storage_getitem_unaligned(lltype.Float, r, 3)
+ assert res == 3.14
free_raw_storage(r)
- assert res == 1<<30
+
class TestRawStorage(BaseRtypingTest):
+
def test_storage_int(self):
def f(i):
r = alloc_raw_storage(24)
- raw_storage_setitem(r, 3, i)
- res = raw_storage_getitem(lltype.Signed, r, 3)
+ raw_storage_setitem(r, 8, i)
+ res = raw_storage_getitem(lltype.Signed, r, 8)
free_raw_storage(r)
return res
+
x = self.interpret(f, [1<<30])
assert x == 1 << 30
+
+ def test_storage_float_unaligned(self, monkeypatch):
+ def f(v):
+ r = alloc_raw_storage(24)
+ raw_storage_setitem_unaligned(r, 3, v)
+ res = raw_storage_getitem_unaligned(lltype.Float, r, 3)
+ free_raw_storage(r)
+ return res
+
+ monkeypatch.setattr(rawstorage, 'misaligned_is_fine', False)
+ x = self.interpret(f, [3.14])
+ assert x == 3.14
+
+
+class TestCBackend(object):
+
+ def test_backend_int(self):
+ def f(i):
+ r = alloc_raw_storage(24)
+ raw_storage_setitem(r, 8, i)
+ res = raw_storage_getitem(lltype.Signed, r, 8)
+ free_raw_storage(r)
+ return res != i
+
+ fc = compile(f, [int])
+ x = fc(-sys.maxint // 3)
+ assert x == 0
+
+ def test_backend_float_unaligned(self, monkeypatch):
+ def f(v):
+ r = alloc_raw_storage(24)
+ raw_storage_setitem_unaligned(r, 3, v)
+ res = raw_storage_getitem_unaligned(lltype.Float, r, 3)
+ free_raw_storage(r)
+ return res != v
+
+ if monkeypatch is not None:
+ monkeypatch.setattr(rawstorage, 'misaligned_is_fine', False)
+ fc = compile(f, [float])
+ x = fc(-3.14)
+ assert x == 0
+
+ def test_backend_float_unaligned_allow_misalign(self):
+ self.test_backend_float_unaligned(monkeypatch=None)
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit