doceme / py-spidev

MIT License
461 stars 203 forks source link

Call Py_DECREF to fix leaked reference counts, should fix #91 #93

Closed Gadgetoid closed 4 years ago

Gadgetoid commented 4 years ago

I finally traced #91 back to a missing Py_DECREF after PySequence_SetItem. Unlike, for example, PyList_SET_ITEM, this function is not reference stealing.

I've added some comments that attempt to clarify the difference between the way this code handles reference stealing and non-reference stealing calls.

Coming along for the ride in this fix is a swap from Py_BuildValue to PyLong_FromLong, which avoids the need for a format string and should- in theory- be faster. This isn't entirely unrelated, since it aims to balance the cost of calling Py_DECREF for every byte, but I have no substantive evidence to back this up.

import spidev
import time

bus = spidev.SpiDev(0, 0)

bus.mode = 0
bus.lsbfirst = False
bus.max_speed_hz = 80 * 1000000

bytes_total = 0
transfers_total = 0
last_update = time.time()
time_start = last_update

while True:
    bus.xfer([0b10101010] * 4096)
    bytes_total += 4096
    transfers_total += 1
    if time.time() - last_update >= 60.0:
        print(f"{time.time() - time_start:.2f} - {bytes_total:,}b {transfers_total:,}")
        last_update = time.time()
doceme commented 4 years ago

Thanks for fixing this!