Author: Armin Rigo <ar...@tunes.org> Branch: stmgc-c8 Changeset: r78281:4da124c51415 Date: 2015-06-24 09:53 +0200 http://bitbucket.org/pypy/pypy/changeset/4da124c51415/
Log: Add unsafe_read(), for a different use case: multiple threads all reading some big shared immutable raw data diff --git a/pypy/module/pypystm/__init__.py b/pypy/module/pypystm/__init__.py --- a/pypy/module/pypystm/__init__.py +++ b/pypy/module/pypystm/__init__.py @@ -31,4 +31,5 @@ 'Empty': 'space.fromcache(queue.Cache).w_Empty', 'unsafe_write': 'unsafe_op.unsafe_write', + 'unsafe_read': 'unsafe_op.unsafe_read', } diff --git a/pypy/module/pypystm/test/test_unsafe_op.py b/pypy/module/pypystm/test/test_unsafe_op.py --- a/pypy/module/pypystm/test/test_unsafe_op.py +++ b/pypy/module/pypystm/test/test_unsafe_op.py @@ -13,6 +13,7 @@ pypystm.unsafe_write(x, 1, '\xAA') assert x[0] == 'A' assert x[1] == '\xAA' + assert pypystm.unsafe_read(x, 1) == '\xAA' def test_unsafe_write_int32(self): import pypystm, _cffi_backend @@ -23,6 +24,7 @@ pypystm.unsafe_write(x, 1, -0x05060708) assert x[0] == -0x01020304 assert x[1] == -0x05060708 + assert pypystm.unsafe_read(x, 1) == -0x05060708 def test_unsafe_write_uint64(self): import pypystm, _cffi_backend @@ -33,6 +35,7 @@ pypystm.unsafe_write(x, 1, 0xF506070855667788) assert x[0] == 0x0102030411223344 assert x[1] == 0xF506070855667788 + assert pypystm.unsafe_read(x, 1) == 0xF506070855667788 def test_unsafe_write_unsupported_case(self): import pypystm, _cffi_backend @@ -40,6 +43,7 @@ BUniCharP = _cffi_backend.new_pointer_type(BUniChar) x = _cffi_backend.newp(_cffi_backend.new_array_type(BUniCharP, 2)) raises(TypeError, pypystm.unsafe_write, x, 0, u'X') + raises(TypeError, pypystm.unsafe_read, x, 1) def test_unsafe_write_float(self): import pypystm, _cffi_backend @@ -50,6 +54,7 @@ pypystm.unsafe_write(x, 1, -42.0) assert x[0] == 12.25 assert x[1] == -42.0 + assert pypystm.unsafe_read(x, 1) == -42.0 def test_unsafe_write_double(self): import pypystm, _cffi_backend @@ -60,3 +65,4 @@ pypystm.unsafe_write(x, 1, -42.0) assert x[0] == 12.25 assert x[1] == -42.0 + assert pypystm.unsafe_read(x, 1) == -42.0 diff --git a/pypy/module/pypystm/unsafe_op.py b/pypy/module/pypystm/unsafe_op.py --- a/pypy/module/pypystm/unsafe_op.py +++ b/pypy/module/pypystm/unsafe_op.py @@ -3,6 +3,7 @@ from pypy.module._cffi_backend import cdataobj, ctypeptr, ctypeprim, misc from rpython.rtyper.lltypesystem import lltype, rffi from rpython.rlib.objectmodel import specialize +from rpython.rlib.rarithmetic import intmask @specialize.memo() @@ -73,3 +74,65 @@ raise oefmt(space.w_TypeError, "unsupported type in unsafe_write(): '%s'", ctitem.name) + +# ____________________________________________________________ + + +def unsafe_read_raw_signed_data(w_cdata, index, size): + with w_cdata as target: + for TP, _ in misc._prim_signed_types: + if size == rffi.sizeof(TP): + TPP = get_unsafe_type_ptr(TP) + value = rffi.cast(TPP, target)[index] + return rffi.cast(lltype.Signed, value) + raise NotImplementedError("bad integer size") + +def unsafe_read_raw_unsigned_data(w_cdata, index, size): + with w_cdata as target: + for TP, _ in misc._prim_unsigned_types: + if size == rffi.sizeof(TP): + TPP = get_unsafe_type_ptr(TP) + value = rffi.cast(TPP, target)[index] + return rffi.cast(lltype.Unsigned, value) + raise NotImplementedError("bad integer size") + +def unsafe_read_raw_float_data(w_cdata, index, size): + with w_cdata as target: + for TP, _ in misc._prim_float_types: + if size == rffi.sizeof(TP): + TPP = get_unsafe_type_ptr(TP) + value = rffi.cast(TPP, target)[index] + return rffi.cast(lltype.Float, value) + raise NotImplementedError("bad integer size") + + +@unwrap_spec(w_cdata=cdataobj.W_CData, index=int) +def unsafe_read(space, w_cdata, index): + ctype = w_cdata.ctype + if not isinstance(ctype, ctypeptr.W_CTypePtrOrArray): + raise oefmt(space.w_TypeError, + "expected a cdata of type pointer or array") + ctitem = ctype.ctitem + + if isinstance(ctitem, ctypeprim.W_CTypePrimitiveChar): + uintvalue = unsafe_read_raw_unsigned_data(w_cdata, index, size=1) + return space.wrap(chr(intmask(uintvalue))) + + if isinstance(ctitem, ctypeprim.W_CTypePrimitiveSigned): + if ctitem.value_fits_long: + intvalue = unsafe_read_raw_signed_data(w_cdata, index, ctitem.size) + return space.wrap(intvalue) + + if isinstance(ctitem, ctypeprim.W_CTypePrimitiveUnsigned): + if ctitem.value_fits_ulong: + uintvalue = unsafe_read_raw_unsigned_data(w_cdata, index, + ctitem.size) + return space.wrap(uintvalue) + + if isinstance(ctitem, ctypeprim.W_CTypePrimitiveFloat): + if not isinstance(ctitem, ctypeprim.W_CTypePrimitiveLongDouble): + floatvalue = unsafe_read_raw_float_data(w_cdata, index, ctitem.size) + return space.wrap(floatvalue) + + raise oefmt(space.w_TypeError, "unsupported type in unsafe_read(): '%s'", + ctitem.name) _______________________________________________ pypy-commit mailing list pypy-commit@python.org https://mail.python.org/mailman/listinfo/pypy-commit