← index #896Issue #865
Related · high · value 0.402
QUERY · ISSUE

Discussion about allocating memory from within an irq

openby dhylandsopened 2014-10-08updated 2024-07-19
rfcports

So I've been thinkng about this, and I think it would be possible to have some type of scratch allocator which could be used inside interrupt handlers.

The actual scratch buffer would be allocated outside of the interrupt and somehow associated with the handler.

When the handler runs it would put the registered handler on top of a list of allocators. When a memory allocation is required, it would either use the scratch allocator, or if none were present, use the heap allocator. The scrath allocator would basically just increment a pointer by the number of bytes being allocated, as long as that number of bytes still exists in the scratch buffer,

Each time the interrupt fires, it would reset the scratch buffer.

I just thought I'd throw this out as an idea.

CANDIDATE · ISSUE

Handle MemoryError in aioble_central.py scanner event

openby brianreinholdopened 2024-05-28updated 2024-05-29

I am using the scanner as follows in my application code

      # The 'scanner' is of type 'scan' defined in aioble
      async with scan(duration_ms=10000,  # The length of the scan cycle in milliseconds. 
                      interval_us=30000,  # The time between each scan listen start
                      window_us=15000,    # The length of time during the scan interval one is actually listening
                                          # If interval_us = window_us the scan is non stop (so called fully duty cycle)
                                          # Background scanning usually sets the window_us to be less than interval_us.
                      active=True) as scanner:    # active = True means do scan requests to get scan responses
                                                  # For PHD we always want to do active scans.

However, every once and a while in the scan event handler a MemoryError is thrown while trying to load a result into the queue shown below:

    if event == _IRQ_SCAN_RESULT:
        addr_type, addr, adv_type, rssi, adv_data = data    # data here is a tuple[int, bytes, int, int, bytes]
        if not _active_scanner:
            return
        try:
            if queue_scan:
                _active_scanner._queue.append((addr_type, bytes(addr), adv_type, rssi, bytes(adv_data)))
                _active_scanner._event.set()
        except MemoryError:
            queue_scan = False
            logger.error('LNI: AIOBLE: Memory allocation error queuing an advertisement/scan response.') # type: ignore
            import gc
            gc.collect()

I have added a handler for the exception and would like to be able to recover from the error but am not sure what else I need to do. With the code shown above, the scanner restarts after 10 seconds but ScanResult objects are no longer created. Not sure why. Do I need to set the event? Do I need to add a filter that blocks repeat advertisements in a given scan cycle? Maybe it is simply not possible to recover from such an error?

Any help is greatly appreciated, especially from the code author.

1 comment
brianreinhold · 2024-05-29

The concept turns out to work, I was just accessing the variable queue_scan as a global variable in the other module. The proper way to access it in the other module if I want to change it is to reference it as a module variable

import aioble_central

then where I want to reset it to True:
aioble_central.queue_scan = True,

This worked. On the MemoryError setting queue_scan to False blocked any further attempt to queue ScanResponses until the queue_scan is reset to True in the module handling the scan cycle (which in this case lasts for 10 seconds)

Keyboard

j / / n
next pair
k / / p
previous pair
1 / / h
show query pane
2 / / l
show candidate pane
c
copy suggested comment
r
toggle reasoning
g i
go to index
?
show this help
esc
close overlays

press ? or esc to close

copied