Author: Brian Kearns <bdkea...@gmail.com> 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 + +@specialize.memo() +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 + +@specialize.ll() +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] + +@specialize.ll() +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 pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit