-
Kirill Smelkov authored
Currently select, via _selcase, requires users to provide pointers to tx and rx buffers. However if element type itself can fit into a pointer word, we can put the element directly into _selcase and mark the case with a flag, that it contains inplace data instead of referring to external storage. This will be helpful in upcoming patch where we'll teach pychan to work with several element types, not only pyobject elements. This patch does careful introduction of _selcase.flags - in such a way that the size of _selcase stays the same as it was before by using bitfields. The .ptxrx pointer is unioned with newly introduced inplace uint64 .itxrx data, which is used by select instead of .ptxrx if the flag is set. The usage of uint64 should not increase _selcase size on 64-bit platforms. Then _selcase.ptx() and .prx() accessors are adapted accordingly and the rest of the changes are corresponding test and _chanselect2<onstack=false> adaptation. This functionality is kind of low-level and is not exposed via any _selsend() or chan.sends() API changes. Whenever inplace tx should be used, the case should be prepared either completely manually, or with e.g. first calling _selsend() and then manually changing .flags and .itxrx. Added test serves as the example on how to do it. Inplace rx is currently forbidden - because supporting that would require to drop const from casev select argument. However in the future, for symmetry, we might want to support that as well. P.S. Since write to selcase.itxrx requires casting pointers e.g. like this: *(int *)&sel[0].itxrx = 12345; it breaks C99 strict aliasing and by default compiler can generate bad code on such pattern. To the problem we adapt the build system to default compiler to no-strict-aliasing (as many other projects do, e.g. Linux kernel) with the idea that in many cases where strict aliasing was intended to help it actually does not, because e.g. pointer types are the same, while explicitly marking pointers with `restrict` keyword does help indeed. Nothing new for Python2 here, as it is using -fno-strict-aliasing by itself. However Python3 is compiling without -fno-strict-aliasing: https://python.org/dev/peps/pep-3123 .
47111d3e